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 2020/09/18 15:53:36 UTC

[camel-spring-boot-examples] 13/40: health check

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-spring-boot-examples.git

commit 5d18472bb2a9403cc79697909a35fb826e98a0a9
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Jun 9 07:38:32 2020 +0200

    health check
---
 camel-example-spring-boot-health-checks/pom.xml    | 10 +++-
 .../readme.adoc                                    |  5 ++
 .../src/main/java/sample/camel/Application.java    |  1 +
 .../sample/camel/ApplicationConfiguration.java     | 62 ----------------------
 ...pplicationCheck.java => MonkeyHealthCheck.java} | 39 ++++++++------
 .../{Application.java => MyConfiguration.java}     | 23 ++++----
 .../{ApplicationCheck.java => MyRouteBuilder.java} | 42 ++++++---------
 .../src/main/resources/application.properties      | 61 +++++++++++++++------
 8 files changed, 108 insertions(+), 135 deletions(-)

diff --git a/camel-example-spring-boot-health-checks/pom.xml b/camel-example-spring-boot-health-checks/pom.xml
index f5dc7cb..13bc89e 100644
--- a/camel-example-spring-boot-health-checks/pom.xml
+++ b/camel-example-spring-boot-health-checks/pom.xml
@@ -70,7 +70,15 @@
         <!-- Camel -->
         <dependency>
             <groupId>org.apache.camel.springboot</groupId>
-            <artifactId>camel-stream-starter</artifactId>
+            <artifactId>camel-core-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel.springboot</groupId>
+            <artifactId>camel-netty-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-management</artifactId>
         </dependency>
     </dependencies>
 
diff --git a/camel-example-spring-boot-health-checks/readme.adoc b/camel-example-spring-boot-health-checks/readme.adoc
index aede7b3..4d211e2 100644
--- a/camel-example-spring-boot-health-checks/readme.adoc
+++ b/camel-example-spring-boot-health-checks/readme.adoc
@@ -23,6 +23,11 @@ $ http://localhost:8080/actuator/health
 The returned response should include the health checks from Apache Camel,
 and as well two custom checks.
 
+=== JMX Management
+
+You can from JMX see the health-check status in the Camel tree under health and
+find the DefaultHealthCheck MBean.
+
 === Help and contributions
 
 If you hit any problem using Camel or have some feedback, then please
diff --git a/camel-example-spring-boot-health-checks/src/main/java/sample/camel/Application.java b/camel-example-spring-boot-health-checks/src/main/java/sample/camel/Application.java
index d7ee3f1..5c8aafa 100644
--- a/camel-example-spring-boot-health-checks/src/main/java/sample/camel/Application.java
+++ b/camel-example-spring-boot-health-checks/src/main/java/sample/camel/Application.java
@@ -25,6 +25,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
  */
 @SpringBootApplication
 public class Application {
+
     /**
      * A main method to start this application.
      */
diff --git a/camel-example-spring-boot-health-checks/src/main/java/sample/camel/ApplicationConfiguration.java b/camel-example-spring-boot-health-checks/src/main/java/sample/camel/ApplicationConfiguration.java
deleted file mode 100644
index aff4530..0000000
--- a/camel-example-spring-boot-health-checks/src/main/java/sample/camel/ApplicationConfiguration.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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 sample.camel;
-
-import org.apache.camel.RuntimeCamelException;
-import org.apache.camel.builder.RouteBuilder;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-public class ApplicationConfiguration {
-
-    @Bean
-    public RouteBuilder routesBuilder() {
-        return new RouteBuilder() {
-            public void configure() throws Exception {
-                // to be less verbose
-                errorHandler(defaultErrorHandler().logStackTrace(false).logExhaustedMessageHistory(false).logExhausted(false));
-
-                from("timer:foo?bridgeErrorHandler=true&period=4000")
-                    .routeId("foo")
-                    .process(e -> {
-                        throw new RuntimeCamelException("This is a forced exception to have health check monitor this failure (route=foo)"); 
-                    });
-                from("timer:bar?bridgeErrorHandler=true&period=5000")
-                    .routeId("bar")
-                    .process(e -> {
-                        throw new RuntimeCamelException("This is a forced exception to have health check monitor this failure (route=bar)");
-                    });
-                from("timer:slow?period=1000")
-                    .routeId("slow")
-                    .process(e -> {
-                        Thread.sleep(1200);
-                    });
-            }
-        };
-    }
-
-    @Bean(name = "my-check-1")
-    public ApplicationCheck applicationHealth1() {
-        return new ApplicationCheck("global", "my-check-1");
-    }
-
-    @Bean(name = "my-check-2")
-    public ApplicationCheck applicationHealth2() {
-        return new ApplicationCheck("local", "my-check-2");
-    }
-}
diff --git a/camel-example-spring-boot-health-checks/src/main/java/sample/camel/ApplicationCheck.java b/camel-example-spring-boot-health-checks/src/main/java/sample/camel/MonkeyHealthCheck.java
similarity index 59%
copy from camel-example-spring-boot-health-checks/src/main/java/sample/camel/ApplicationCheck.java
copy to camel-example-spring-boot-health-checks/src/main/java/sample/camel/MonkeyHealthCheck.java
index 9b73bc3..6ece658 100644
--- a/camel-example-spring-boot-health-checks/src/main/java/sample/camel/ApplicationCheck.java
+++ b/camel-example-spring-boot-health-checks/src/main/java/sample/camel/MonkeyHealthCheck.java
@@ -17,33 +17,38 @@
 package sample.camel;
 
 import java.util.Map;
-import java.util.UUID;
 
 import org.apache.camel.health.HealthCheckResultBuilder;
 import org.apache.camel.impl.health.AbstractHealthCheck;
 
-public class ApplicationCheck extends AbstractHealthCheck {
-    private State state;
-
-    public ApplicationCheck(String group, String id) {
-        super(group, id);
+/**
+ * A chaos monkey health check that reports UP or DOWN in a chaotic way.
+ *
+ * This is a custom implementation of a Camel {@link org.apache.camel.health.HealthCheck}
+ * which is automatic discovered if bound in the {@link org.apache.camel.spi.Registry} and
+ * used as part of Camel's health-check system.
+ */
+public class MonkeyHealthCheck extends AbstractHealthCheck {
 
-        this.state = State.UP;
+    private boolean up = true;
 
-        getConfiguration().setEnabled(true);
+    protected MonkeyHealthCheck() {
+        super("custom", "monkey");
     }
 
-
-    public State getState() {
-        return state;
+    @Override
+    protected void doCall(HealthCheckResultBuilder builder, Map<String, Object> options) {
+        builder.detail("monkey", "The chaos monkey was here");
+        if (up) {
+            builder.up();
+        } else {
+            builder.down();
+        }
     }
 
-    public void setState(State state) {
-        this.state = state;
+    public String chaos() {
+        up = !up;
+        return up ? "All is okay" : "Chaos monkey was here";
     }
 
-    @Override
-    protected void doCall(HealthCheckResultBuilder builder, Map<String, Object> options) {
-        builder.state(state).detail("random.value", UUID.randomUUID().toString());
-    }
 }
diff --git a/camel-example-spring-boot-health-checks/src/main/java/sample/camel/Application.java b/camel-example-spring-boot-health-checks/src/main/java/sample/camel/MyConfiguration.java
similarity index 65%
copy from camel-example-spring-boot-health-checks/src/main/java/sample/camel/Application.java
copy to camel-example-spring-boot-health-checks/src/main/java/sample/camel/MyConfiguration.java
index d7ee3f1..33259f2 100644
--- a/camel-example-spring-boot-health-checks/src/main/java/sample/camel/Application.java
+++ b/camel-example-spring-boot-health-checks/src/main/java/sample/camel/MyConfiguration.java
@@ -16,20 +16,15 @@
  */
 package sample.camel;
 
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
 
-//CHECKSTYLE:OFF
-/**
- * A sample Spring Boot application that starts the Camel routes.
- */
-@SpringBootApplication
-public class Application {
-    /**
-     * A main method to start this application.
-     */
-    public static void main(String[] args) {
-        SpringApplication.run(Application.class, args);
+@Configuration
+public class MyConfiguration {
+
+    @Bean(name = "monkey")
+    public MonkeyHealthCheck newMonkey() {
+        return new MonkeyHealthCheck();
     }
+
 }
-//CHECKSTYLE:ON
diff --git a/camel-example-spring-boot-health-checks/src/main/java/sample/camel/ApplicationCheck.java b/camel-example-spring-boot-health-checks/src/main/java/sample/camel/MyRouteBuilder.java
similarity index 53%
rename from camel-example-spring-boot-health-checks/src/main/java/sample/camel/ApplicationCheck.java
rename to camel-example-spring-boot-health-checks/src/main/java/sample/camel/MyRouteBuilder.java
index 9b73bc3..b1cbbe1 100644
--- a/camel-example-spring-boot-health-checks/src/main/java/sample/camel/ApplicationCheck.java
+++ b/camel-example-spring-boot-health-checks/src/main/java/sample/camel/MyRouteBuilder.java
@@ -16,34 +16,26 @@
  */
 package sample.camel;
 
-import java.util.Map;
-import java.util.UUID;
+import org.apache.camel.builder.RouteBuilder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
 
-import org.apache.camel.health.HealthCheckResultBuilder;
-import org.apache.camel.impl.health.AbstractHealthCheck;
+@Component
+public class MyRouteBuilder extends RouteBuilder {
 
-public class ApplicationCheck extends AbstractHealthCheck {
-    private State state;
-
-    public ApplicationCheck(String group, String id) {
-        super(group, id);
-
-        this.state = State.UP;
-
-        getConfiguration().setEnabled(true);
-    }
-
-
-    public State getState() {
-        return state;
-    }
-
-    public void setState(State state) {
-        this.state = state;
-    }
+    // we can inject the bean via this annotation
+    @Autowired
+    MonkeyHealthCheck monkey;
 
     @Override
-    protected void doCall(HealthCheckResultBuilder builder, Map<String, Object> options) {
-        builder.state(state).detail("random.value", UUID.randomUUID().toString());
+    public void configure() throws Exception {
+        from("timer:foo?period={{myPeriod}}").routeId("timer")
+                .bean(monkey, "chaos")
+                .log("${body}");
+
+        // this route is invalid and fails during startup
+        // the supervising route controller will take over and attempt
+        // to restart this route
+        from("netty:tcp:unknownhost").to("log:dummy").routeId("netty");
     }
 }
diff --git a/camel-example-spring-boot-health-checks/src/main/resources/application.properties b/camel-example-spring-boot-health-checks/src/main/resources/application.properties
index 2a89be8..9077b44 100644
--- a/camel-example-spring-boot-health-checks/src/main/resources/application.properties
+++ b/camel-example-spring-boot-health-checks/src/main/resources/application.properties
@@ -31,26 +31,55 @@ management.endpoint.health.show-details=always
 
 camel.springboot.name = SampleHealthChecks
 
-################################################################################
-#
-# health checks
-#
-################################################################################
+# enable JMX which allows to also control health check
+camel.springboot.jmx-enabled = true
 
-# Enable camel health check
-camel.health.enabled = true
+# enable supervised route controller which will startup routes in safe manner
+camel.springboot.route-controller-supervise-enabled = true
+
+# attempt up till 10 times to start a route (and exhaust if still failing)
+# when a route is exhausted then its taken out as being supervised and
+# will not take part of health-check either (UNKNOWN state)
+camel.springboot.route-controller-back-off-max-attempts = 10
+# when starting a route (and restarts) fails all attempts
+# then we can control whether the route should be influence the health-check
+# and report the route as either UNKNOWN or DOWN. Setting this option to true
+# will report it as DOWN otherwise its UNKNOWN
+###camel.springboot.route-controller-unhealthy-on-exhausted = true
 
-# Enable camel HealthCheck for routes.
+# enable health check (is automatic enabled if discovered on classpath)
+# global flag to enable/disable
+camel.health.enabled = true
+# context check is default included but we can turn it on|off
+camel.health.context-enabled = true
+# routes check is default included but we can turn it on|off
 camel.health.routes-enabled = true
+# registry check is default included but we can turn it on|off
+camel.health.registry-enabled = true
+
+# you can turn on or off individual routes as shown below
+### camel.heath.config[timer].parent = routes
+### camel.heath.config[timer].enabled = true
+### camel.heath.config[netty].check = routes
+### camel.heath.config[netty].enabled = false
 
-# fine grained configuration for foo route
-camel.health.config[foo].parent=routes
-camel.health.config[foo].interval=10000
-camel.health.config[foo].failure-threshold=5
+# and configure each individually
+camel.health.config[timer].parent = routes
+camel.health.config[timer].interval = 5000
+camel.health.config[netty].parent = routes
+camel.health.config[netty].interval = 20000
+camel.health.config[netty].failure-threshold = 10
 
-# fine grained configuration for bar route
-camel.health.config[bar].parent=routes
-camel.health.config[bar].interval=10000
-camel.health.config[bar].failure-threshold=10
+# find grained routes configuration per route (support wildcards)
+# (enabled is default true for discovered health-checks)
+### camel.health.config[*].enabled = true
 
+# allow 5 failures with 10s apart as slack to handle routes being flaky
+# however if after 5 failures then the state will be regarded as DOWN onwards
+# (the route can recover and the state will then be UP)
+###camel.health.config[*].parent = routes
+###camel.health.config[*].interval = 10s
+###camel.health.config[*].failure-threshold = 5
 
+# properties used in the route
+myPeriod = 10s