You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2019/11/18 09:00:57 UTC

[camel] 15/23: CAMEL-13691: camel-resilience4j - WIP

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

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

commit 07735378728cd7ef6a3c3b79a00442d90f22d035
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Nov 18 05:42:41 2019 +0100

    CAMEL-13691: camel-resilience4j - WIP
---
 .../resilience4j/ResilienceProcessor.java          | 12 +++-
 .../component/resilience4j/ResilienceReifier.java  |  7 +++
 .../ResilienceExistingCircuitBreakerTest.java      | 68 ++++++++++++++++++++++
 .../model/Resilience4jConfigurationCommon.java     | 16 +++++
 .../model/Resilience4jConfigurationDefinition.java | 11 ++++
 .../main/Resilience4jConfigurationProperties.java  | 24 ++++++++
 .../camel-main-configuration-metadata.json         |  6 ++
 .../modules/ROOT/pages/resilience4j.adoc           | 12 ----
 8 files changed, 143 insertions(+), 13 deletions(-)

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 c936a9e..93eea8e 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
@@ -99,6 +99,14 @@ public class ResilienceProcessor extends AsyncProcessorSupport implements CamelC
         this.id = id;
     }
 
+    public CircuitBreaker getCircuitBreaker() {
+        return circuitBreaker;
+    }
+
+    public void setCircuitBreaker(CircuitBreaker circuitBreaker) {
+        this.circuitBreaker = circuitBreaker;
+    }
+
     public boolean isShutdownExecutorService() {
         return shutdownExecutorService;
     }
@@ -374,7 +382,9 @@ public class ResilienceProcessor extends AsyncProcessorSupport implements CamelC
     @Override
     protected void doStart() throws Exception {
         ObjectHelper.notNull(camelContext, "CamelContext", this);
-        circuitBreaker = CircuitBreaker.of(id, circuitBreakerConfig);
+        if (circuitBreaker == null) {
+            circuitBreaker = CircuitBreaker.of(id, circuitBreakerConfig);
+        }
     }
 
     @Override
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 e9aa90c..0e89786 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
@@ -23,6 +23,7 @@ import java.util.Optional;
 import java.util.concurrent.ExecutorService;
 
 import io.github.resilience4j.bulkhead.BulkheadConfig;
+import io.github.resilience4j.circuitbreaker.CircuitBreaker;
 import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
 
 import io.github.resilience4j.timelimiter.TimeLimiterConfig;
@@ -37,6 +38,7 @@ import org.apache.camel.model.Resilience4jConfigurationDefinition;
 import org.apache.camel.reifier.ProcessorReifier;
 import org.apache.camel.spi.BeanIntrospection;
 import org.apache.camel.spi.RouteContext;
+import org.apache.camel.support.CamelContextHelper;
 import org.apache.camel.support.PropertyBindingSupport;
 import org.apache.camel.util.function.Suppliers;
 
@@ -72,6 +74,11 @@ public class ResilienceReifier extends ProcessorReifier<CircuitBreakerDefinition
 
         ResilienceProcessor answer = new ResilienceProcessor(cbConfig, bhConfig, tlConfig, processor, fallback);
         configureTimeoutExecutorService(answer, routeContext, config);
+        // using any existing circuit breakers?
+        if (config.getCircuitBreakerRef() != null) {
+            CircuitBreaker cb = CamelContextHelper.mandatoryLookup(routeContext.getCamelContext(), config.getCircuitBreakerRef(), CircuitBreaker.class);
+            answer.setCircuitBreaker(cb);
+        }
         return answer;
     }
 
diff --git a/components/camel-resilience4j/src/test/java/org/apache/camel/component/resilience4j/ResilienceExistingCircuitBreakerTest.java b/components/camel-resilience4j/src/test/java/org/apache/camel/component/resilience4j/ResilienceExistingCircuitBreakerTest.java
new file mode 100644
index 0000000..8892659
--- /dev/null
+++ b/components/camel-resilience4j/src/test/java/org/apache/camel/component/resilience4j/ResilienceExistingCircuitBreakerTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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;
+
+import io.github.resilience4j.circuitbreaker.CircuitBreaker;
+import org.apache.camel.BindToRegistry;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.spi.CircuitBreakerConstants;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+public class ResilienceExistingCircuitBreakerTest extends CamelTestSupport {
+
+    @BindToRegistry
+    public CircuitBreaker myCircuitBreaker() {
+        return CircuitBreaker.ofDefaults("myCircuitBreaker");
+    }
+
+    @Test
+    public void testResilience() throws Exception {
+        getMockEndpoint("mock:result").expectedBodiesReceived("Fallback message");
+        getMockEndpoint("mock:result").expectedPropertyReceived(CircuitBreakerConstants.RESPONSE_SUCCESSFUL_EXECUTION, false);
+        getMockEndpoint("mock:result").expectedPropertyReceived(CircuitBreakerConstants.RESPONSE_FROM_FALLBACK, true);
+
+        template.sendBody("direct:start", "Hello World");
+
+        assertMockEndpointsSatisfied();
+
+        CircuitBreaker cb = context().getRegistry().lookupByNameAndType("myCircuitBreaker", CircuitBreaker.class);
+        assertNotNull(cb);
+        assertEquals("myCircuitBreaker", cb.getName());
+        assertEquals(0, cb.getMetrics().getNumberOfSuccessfulCalls());
+        assertEquals(1, cb.getMetrics().getNumberOfFailedCalls());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                    .to("log:start")
+                    .circuitBreaker().resilience4jConfiguration().circuitBreakerRef("myCircuitBreaker").end()
+                        .throwException(new IllegalArgumentException("Forced"))
+                    .onFallback()
+                        .transform().constant("Fallback message")
+                    .end()
+                    .to("log:result")
+                    .to("mock:result");
+            }
+        };
+    }
+
+}
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/Resilience4jConfigurationCommon.java b/core/camel-core-engine/src/main/java/org/apache/camel/model/Resilience4jConfigurationCommon.java
index decdd34..15eed28 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/model/Resilience4jConfigurationCommon.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/model/Resilience4jConfigurationCommon.java
@@ -28,6 +28,9 @@ public class Resilience4jConfigurationCommon extends IdentifiedType {
 
     @XmlAttribute
     @Metadata(label = "circuitbreaker")
+    private String circuitBreakerRef;
+    @XmlAttribute
+    @Metadata(label = "circuitbreaker")
     private String configRef;
     @XmlAttribute
     @Metadata(label = "circuitbreaker", defaultValue = "50")
@@ -77,6 +80,19 @@ public class Resilience4jConfigurationCommon extends IdentifiedType {
     // Getter/Setter
     // -------------------------------------------------------------------------
 
+    public String getCircuitBreakerRef() {
+        return circuitBreakerRef;
+    }
+
+    /**
+     * 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.
+     */
+    public void setCircuitBreakerRef(String circuitBreakerRef) {
+        this.circuitBreakerRef = circuitBreakerRef;
+    }
+
     public String getConfigRef() {
         return configRef;
     }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/Resilience4jConfigurationDefinition.java b/core/camel-core-engine/src/main/java/org/apache/camel/model/Resilience4jConfigurationDefinition.java
index 54d4f0d..f9b100c 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/model/Resilience4jConfigurationDefinition.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/model/Resilience4jConfigurationDefinition.java
@@ -46,6 +46,17 @@ public class Resilience4jConfigurationDefinition extends Resilience4jConfigurati
     // -------------------------------------------------------------------------
 
     /**
+     * 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.
+     */
+    public Resilience4jConfigurationDefinition circuitBreakerRef(String circuitBreakerRef) {
+        setCircuitBreakerRef(circuitBreakerRef);
+        return this;
+    }
+
+
+    /**
      * Refers to an existing io.github.resilience4j.circuitbreaker.CircuitBreakerConfig instance
      * to lookup and use from the registry.
      */
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 9292287..35d5c95 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
@@ -25,6 +25,7 @@ public class Resilience4jConfigurationProperties {
 
     private final MainConfigurationProperties parent;
 
+    private String circuitBreakerRef;
     private String configRef;
     private Float failureRateThreshold;
     private Integer permittedNumberOfCallsInHalfOpenState;
@@ -55,6 +56,19 @@ public class Resilience4jConfigurationProperties {
     // getter and setters
     // --------------------------------------------------------------
 
+    public String getCircuitBreakerRef() {
+        return circuitBreakerRef;
+    }
+
+    /**
+     * 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.
+     */
+    public void setCircuitBreakerRef(String circuitBreakerRef) {
+        this.circuitBreakerRef = circuitBreakerRef;
+    }
+
     public String getConfigRef() {
         return configRef;
     }
@@ -295,6 +309,16 @@ public class Resilience4jConfigurationProperties {
     }
 
     /**
+     * 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.
+     */
+    public Resilience4jConfigurationProperties withCircuitBreakerRef(String circuitBreakerRef) {
+        this.circuitBreakerRef = circuitBreakerRef;
+        return this;
+    }
+
+    /**
      * Refers to an existing io.github.resilience4j.circuitbreaker.CircuitBreakerConfig instance
      * to lookup and use from the registry.
      */
diff --git a/core/camel-main/src/main/resources/META-INF/camel-main-configuration-metadata.json b/core/camel-main/src/main/resources/META-INF/camel-main-configuration-metadata.json
index 983efdb..3a6ba44 100644
--- a/core/camel-main/src/main/resources/META-INF/camel-main-configuration-metadata.json
+++ b/core/camel-main/src/main/resources/META-INF/camel-main-configuration-metadata.json
@@ -646,6 +646,12 @@
 			"description":"Configures a maximum amount of time which the calling thread will wait to enter the bulkhead. If bulkhead has space available, entry is guaranteed and immediate. If bulkhead is full, calling threads will contest for space, if it becomes available. maxWaitDuration can be set to 0. Note: for threads running on an event-loop or equivalent (rx computation pool, etc), setting maxWaitDuration to 0 is highly recommended. Blocking an event-loop thread will most likely have a ne [...]
 		},
 		{
+			"name":"camel.resilience4j.circuit-breaker-ref",
+			"type":"java.lang.String",
+			"sourceType":"org.apache.camel.main.Resilience4jConfigurationProperties",
+			"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."
+		},
+		{
 			"name":"camel.resilience4j.config-ref",
 			"type":"java.lang.String",
 			"sourceType":"org.apache.camel.main.Resilience4jConfigurationProperties",
diff --git a/docs/components/modules/ROOT/pages/resilience4j.adoc b/docs/components/modules/ROOT/pages/resilience4j.adoc
index 6801015..396a526 100644
--- a/docs/components/modules/ROOT/pages/resilience4j.adoc
+++ b/docs/components/modules/ROOT/pages/resilience4j.adoc
@@ -35,16 +35,4 @@ When using Spring Boot make sure to use the following Maven dependency to have s
 </dependency>
 ----
 
-
-The component supports 3 options, which are listed below.
-
-
-
-[width="100%",cols="2,5,^1,2",options="header"]
-|===
-| Name | Description | Default | Type
-| *camel.component.hystrix.mapping.enabled* | Enables the automatic mapping of the hystrics metric servlet into the Spring web context. | true | Boolean
-| *camel.component.hystrix.mapping.path* | Endpoint for hystrix metrics servlet. | /hystrix.stream | String
-| *camel.component.hystrix.mapping.servlet-name* | Name of the Hystrix metrics servlet. | HystrixEventStreamServlet | String
-|===
 // spring-boot-auto-configure options: END