This is an automated email from the ASF dual-hosted git repository. fmariani pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-spring-boot.git
commit 541e488059c88ec075b7a47ebc25d7b7d22e6e1d Author: Croway <federico.mariani.1...@gmail.com> AuthorDate: Wed Nov 8 15:59:10 2023 +0100 CAMEL-19648: readiness/liveness probes --- .../src/main/docs/spring-boot.adoc | 21 +++++++ .../CamelAvailabilityCheckAutoConfiguration.java | 50 ++++++++++++++++ .../CamelLivenessStateHealthIndicator.java | 55 ++++++++++++++++++ .../CamelReadinessStateHealthIndicator.java | 67 ++++++++++++++++++++++ ...rk.boot.autoconfigure.AutoConfiguration.imports | 1 + 5 files changed, 194 insertions(+) diff --git a/core/camel-spring-boot/src/main/docs/spring-boot.adoc b/core/camel-spring-boot/src/main/docs/spring-boot.adoc index 25c527237f2..e29685efea7 100644 --- a/core/camel-spring-boot/src/main/docs/spring-boot.adoc +++ b/core/camel-spring-boot/src/main/docs/spring-boot.adoc @@ -416,3 +416,24 @@ implementing your custom https://docs.spring.io/spring-boot/docs/current/referen or by providing GraalVM JSON hint files that can be generated by the https://docs.spring.io/spring-boot/docs/current/reference/html/native-image.html#native-image.advanced.using-the-tracing-agent[Tracing Agent]. For more details about `GraalVM Native Image Support` in Spring Boot please refer to https://docs.spring.io/spring-boot/docs/current/reference/html/native-image.html + +== Camel Readiness and Liveness State Indicators + +Camel specific Readiness and Liveness checks can be added to a Spring Boot 3 application including respectively in the +readiness and livenss groups camelLivenessStateHealthIndicator and camelReadinessStateHealthIndicator. In particular: + +[source,properties] +---- +management.endpoint.health.group.liveness.include=livenessState,camelLivenessState +management.endpoint.health.group.readiness.include=readinessState,camelReadinessState +---- + +Using Camel specific readiness and liveness health indicators, the probes will be augmented with camel components +health checks that support this feature. In enable the probes locally, they need to be enabled + +[source,properties] +---- +management.endpoint.health.probes.enabled=true +---- + +Finally, http://localhost:8080/actuator/health/liveness will show the updated probe. \ No newline at end of file diff --git a/core/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/health/CamelAvailabilityCheckAutoConfiguration.java b/core/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/health/CamelAvailabilityCheckAutoConfiguration.java new file mode 100644 index 00000000000..431bee40525 --- /dev/null +++ b/core/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/health/CamelAvailabilityCheckAutoConfiguration.java @@ -0,0 +1,50 @@ +/* + * 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.spring.boot.actuate.health; + +import org.apache.camel.CamelContext; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.spring.boot.actuate.health.liveness.CamelLivenessStateHealthIndicator; +import org.apache.camel.spring.boot.actuate.health.readiness.CamelReadinessStateHealthIndicator; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.availability.ApplicationAvailability; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration(proxyBeanMethods = false) +@AutoConfigureAfter({CamelAutoConfiguration.class, ApplicationAvailabilityAutoConfiguration.class}) +@ConditionalOnBean(CamelAutoConfiguration.class) +public class CamelAvailabilityCheckAutoConfiguration { + + @Bean + @ConditionalOnMissingBean(CamelLivenessStateHealthIndicator.class) + public CamelLivenessStateHealthIndicator camelLivenessStateHealthIndicator(ApplicationAvailability applicationAvailability, + CamelContext camelContext) { + return new CamelLivenessStateHealthIndicator(applicationAvailability, camelContext); + } + + @Bean + @ConditionalOnMissingBean({CamelReadinessStateHealthIndicator.class}) + public CamelReadinessStateHealthIndicator camelReadinessStateHealthIndicator( + ApplicationAvailability applicationAvailability, + CamelContext camelContext) { + return new CamelReadinessStateHealthIndicator(applicationAvailability, camelContext); + } +} \ No newline at end of file diff --git a/core/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/health/liveness/CamelLivenessStateHealthIndicator.java b/core/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/health/liveness/CamelLivenessStateHealthIndicator.java new file mode 100644 index 00000000000..52c47966826 --- /dev/null +++ b/core/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/health/liveness/CamelLivenessStateHealthIndicator.java @@ -0,0 +1,55 @@ +/* + * 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.spring.boot.actuate.health.liveness; + +import org.apache.camel.CamelContext; +import org.apache.camel.health.HealthCheck; +import org.apache.camel.health.HealthCheckHelper; +import org.apache.camel.spring.boot.actuate.health.readiness.CamelReadinessStateHealthIndicator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.actuate.availability.LivenessStateHealthIndicator; +import org.springframework.boot.availability.ApplicationAvailability; +import org.springframework.boot.availability.AvailabilityState; +import org.springframework.boot.availability.LivenessState; + +import java.util.Collection; + +public class CamelLivenessStateHealthIndicator extends LivenessStateHealthIndicator { + + private static final Logger LOG = LoggerFactory.getLogger(CamelLivenessStateHealthIndicator.class); + + private CamelContext camelContext; + + public CamelLivenessStateHealthIndicator( + ApplicationAvailability availability, + CamelContext camelContext) { + super(availability); + + this.camelContext = camelContext; + } + + @Override + protected AvailabilityState getState(ApplicationAvailability applicationAvailability) { + Collection<HealthCheck.Result> results = HealthCheckHelper.invokeLiveness(camelContext); + + boolean isLive = CamelReadinessStateHealthIndicator.checkState(results, LOG); + + return isLive ? + LivenessState.CORRECT : LivenessState.BROKEN; + } +} \ No newline at end of file diff --git a/core/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/health/readiness/CamelReadinessStateHealthIndicator.java b/core/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/health/readiness/CamelReadinessStateHealthIndicator.java new file mode 100644 index 00000000000..8706093dfa5 --- /dev/null +++ b/core/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/actuate/health/readiness/CamelReadinessStateHealthIndicator.java @@ -0,0 +1,67 @@ +/* + * 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.spring.boot.actuate.health.readiness; + +import org.apache.camel.CamelContext; +import org.apache.camel.health.HealthCheck; +import org.apache.camel.health.HealthCheckHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.actuate.availability.ReadinessStateHealthIndicator; +import org.springframework.boot.availability.ApplicationAvailability; +import org.springframework.boot.availability.AvailabilityState; +import org.springframework.boot.availability.ReadinessState; + +import java.util.Collection; + +public class CamelReadinessStateHealthIndicator extends ReadinessStateHealthIndicator { + + private static final Logger LOG = LoggerFactory.getLogger(CamelReadinessStateHealthIndicator.class); + + private CamelContext camelContext; + + public CamelReadinessStateHealthIndicator( + ApplicationAvailability availability, + CamelContext camelContext) { + super(availability); + + this.camelContext = camelContext; + } + + @Override + protected AvailabilityState getState(ApplicationAvailability applicationAvailability) { + Collection<HealthCheck.Result> results = HealthCheckHelper.invokeReadiness(camelContext); + + boolean isReady = checkState(results, LOG); + + return isReady ? + ReadinessState.ACCEPTING_TRAFFIC : ReadinessState.REFUSING_TRAFFIC; + } + + public static boolean checkState(Collection<HealthCheck.Result> results, Logger log) { + boolean isUp = true; + for (HealthCheck.Result result : results) { + if (!HealthCheck.State.UP.equals(result.getState())) { + isUp = false; + + result.getError().ifPresent(error -> log.warn(result.getCheck().getId(), error)); + } + } + + return isUp; + } +} \ No newline at end of file diff --git a/core/camel-spring-boot/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/core/camel-spring-boot/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 58e74acca75..8532b4fa82e 100644 --- a/core/camel-spring-boot/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/core/camel-spring-boot/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -20,6 +20,7 @@ org.apache.camel.spring.boot.actuate.console.CamelDevConsoleAutoConfiguration org.apache.camel.spring.boot.actuate.endpoint.CamelRouteControllerEndpointAutoConfiguration org.apache.camel.spring.boot.actuate.endpoint.CamelRoutesEndpointAutoConfiguration org.apache.camel.spring.boot.actuate.health.CamelHealthCheckAutoConfiguration +org.apache.camel.spring.boot.actuate.health.CamelAvailabilityCheckAutoConfiguration org.apache.camel.spring.boot.actuate.info.CamelInfoAutoConfiguration org.apache.camel.spring.boot.cloud.CamelCloudAutoConfiguration org.apache.camel.spring.boot.cloud.CamelCloudServiceCallConfigurationAutoConfiguration