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 2021/11/30 20:30:55 UTC
[camel] 04/10: CAMEL-15133: camel-health - Resolve health-checks from classpath and make it friendlier to provide custom health checks.
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 330346fbd9ea771d247f1dae6a039e64096fab6a
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Nov 30 15:00:27 2021 +0100
CAMEL-15133: camel-health - Resolve health-checks from classpath and make it friendlier to provide custom health checks.
---
.../apache/camel/health/HealthCheckRegistry.java | 6 ++
.../camel/impl/engine/AbstractCamelContext.java | 16 +++++-
.../FastAnnotationTypeConverterLoader.java | 1 +
.../impl/health/DefaultHealthCheckRegistry.java | 23 ++++++++
.../impl/health/DefaultHealthChecksLoader.java | 65 ++++++++++++++++++++++
5 files changed, 109 insertions(+), 2 deletions(-)
diff --git a/core/camel-api/src/main/java/org/apache/camel/health/HealthCheckRegistry.java b/core/camel-api/src/main/java/org/apache/camel/health/HealthCheckRegistry.java
index c2b3523..9f28f33 100644
--- a/core/camel-api/src/main/java/org/apache/camel/health/HealthCheckRegistry.java
+++ b/core/camel-api/src/main/java/org/apache/camel/health/HealthCheckRegistry.java
@@ -115,4 +115,10 @@ public interface HealthCheckRegistry extends CamelContextAware, StaticService, I
* Returns a sequential {@code Stream} with the known {@link HealthCheck} as its source.
*/
Stream<HealthCheck> stream();
+
+ /**
+ * Loads custom health checks by scanning classpath.
+ */
+ void loadHealthChecks();
+
}
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index e1a1498..0c3b44b 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -2737,7 +2737,19 @@ public abstract class AbstractCamelContext extends BaseService
// ensure additional type converters is loaded
if (loadTypeConverters && typeConverter instanceof AnnotationScanTypeConverters) {
+ StartupStep step2 = startupStepRecorder.beginStep(CamelContext.class, null, "Scan TypeConverters");
((AnnotationScanTypeConverters) typeConverter).scanTypeConverters();
+ startupStepRecorder.endStep(step2);
+ }
+
+ // ensure additional health checks is loaded
+ if (loadHealthChecks) {
+ StartupStep step3 = startupStepRecorder.beginStep(CamelContext.class, null, "Scan HealthChecks");
+ HealthCheckRegistry hcr = getExtension(HealthCheckRegistry.class);
+ if (hcr != null) {
+ hcr.loadHealthChecks();
+ }
+ startupStepRecorder.endStep(step3);
}
// custom properties may use property placeholders so resolve those
@@ -2821,7 +2833,7 @@ public abstract class AbstractCamelContext extends BaseService
bindDataFormats();
- // start components
+ // init components
ServiceHelper.initService(components.values());
// create route definitions from route templates if we have any sources
@@ -2881,7 +2893,7 @@ public abstract class AbstractCamelContext extends BaseService
@Override
protected void doStart() throws Exception {
if (firstStartDone) {
- // its not good practice to reset a camel context
+ // its not good practice resetting a camel context
LOG.warn("Starting CamelContext: {} after the context has been stopped is not recommended", getName());
}
StartupStep step = startupStepRecorder.beginStep(CamelContext.class, getName(), "Start CamelContext");
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/converter/FastAnnotationTypeConverterLoader.java b/core/camel-base/src/main/java/org/apache/camel/impl/converter/FastAnnotationTypeConverterLoader.java
index 7614f73..6c08c48 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/converter/FastAnnotationTypeConverterLoader.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/converter/FastAnnotationTypeConverterLoader.java
@@ -19,6 +19,7 @@ package org.apache.camel.impl.converter;
import org.apache.camel.Converter;
import org.apache.camel.spi.PackageScanClassResolver;
+@Deprecated
public final class FastAnnotationTypeConverterLoader extends AnnotationTypeConverterLoader {
public FastAnnotationTypeConverterLoader(PackageScanClassResolver resolver) {
diff --git a/core/camel-health/src/main/java/org/apache/camel/impl/health/DefaultHealthCheckRegistry.java b/core/camel-health/src/main/java/org/apache/camel/impl/health/DefaultHealthCheckRegistry.java
index 7d2140b..3f23821 100644
--- a/core/camel-health/src/main/java/org/apache/camel/impl/health/DefaultHealthCheckRegistry.java
+++ b/core/camel-health/src/main/java/org/apache/camel/impl/health/DefaultHealthCheckRegistry.java
@@ -16,6 +16,7 @@
*/
package org.apache.camel.impl.health;
+import java.util.Collection;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
@@ -31,6 +32,8 @@ import org.apache.camel.health.HealthCheckRepository;
import org.apache.camel.health.HealthCheckResolver;
import org.apache.camel.support.service.ServiceSupport;
import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.StopWatch;
+import org.apache.camel.util.TimeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -47,6 +50,7 @@ public class DefaultHealthCheckRegistry extends ServiceSupport implements Health
private final Set<HealthCheckRepository> repositories;
private CamelContext camelContext;
private boolean enabled = true;
+ private volatile boolean loadHealthChecksDone;
public DefaultHealthCheckRegistry() {
this(null);
@@ -223,6 +227,25 @@ public class DefaultHealthCheckRegistry extends ServiceSupport implements Health
return Stream.empty();
}
+ @Override
+ public void loadHealthChecks() {
+ StopWatch watch = new StopWatch();
+
+ if (!loadHealthChecksDone) {
+ loadHealthChecksDone = true;
+
+ DefaultHealthChecksLoader loader = new DefaultHealthChecksLoader(
+ camelContext.adapt(ExtendedCamelContext.class).getPackageScanResourceResolver());
+ Collection<HealthCheck> col = loader.loadHealthChecks();
+
+ // report how many health checks we have loaded
+ if (col.size() > 0) {
+ String time = TimeUtils.printDuration(watch.taken());
+ LOG.info("Health checks (scanned: {}) loaded in {}", col.size(), time);
+ }
+ }
+ }
+
private void checkIfAccepted(Object obj) {
boolean accept = obj instanceof HealthCheck || obj instanceof HealthCheckRepository;
if (!accept) {
diff --git a/core/camel-health/src/main/java/org/apache/camel/impl/health/DefaultHealthChecksLoader.java b/core/camel-health/src/main/java/org/apache/camel/impl/health/DefaultHealthChecksLoader.java
new file mode 100644
index 0000000..750fd6e
--- /dev/null
+++ b/core/camel-health/src/main/java/org/apache/camel/impl/health/DefaultHealthChecksLoader.java
@@ -0,0 +1,65 @@
+/*
+ * 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.impl.health;
+
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.camel.health.HealthCheck;
+import org.apache.camel.spi.PackageScanResourceResolver;
+import org.apache.camel.spi.Resource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * To load custom health-checks by classpath scanning.
+ */
+public class DefaultHealthChecksLoader {
+
+ public static final String META_INF_SERVICES = "META-INF/services/org/apache/camel/health-check";
+ private static final Logger LOG = LoggerFactory.getLogger(DefaultHealthChecksLoader.class);
+ private static final Charset UTF8 = Charset.forName("UTF-8");
+
+ protected PackageScanResourceResolver resolver;
+ protected Set<Class<?>> visitedClasses = new HashSet<>();
+ protected Set<String> visitedURIs = new HashSet<>();
+
+ public DefaultHealthChecksLoader(PackageScanResourceResolver resolver) {
+ this.resolver = resolver;
+ }
+
+ public Collection<HealthCheck> loadHealthChecks() {
+ Collection<HealthCheck> answer = new ArrayList<>();
+
+ LOG.trace("Searching for {} health checks", META_INF_SERVICES);
+
+ try {
+ Collection<Resource> resources = resolver.findResources(META_INF_SERVICES + "/*-check");
+ for (Resource resource : resources) {
+ System.out.println(resource);
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+
+ return answer;
+ }
+
+}