Skip to content

Commit

Permalink
Simplify health checks
Browse files Browse the repository at this point in the history
  • Loading branch information
turing85 committed Aug 2, 2024
1 parent 99c2884 commit 480f18b
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 178 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package io.quarkus.artemis.core.deployment.health;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import jakarta.enterprise.context.ApplicationScoped;

Expand All @@ -13,9 +13,7 @@
import io.quarkus.artemis.core.deployment.ArtemisJmsBuildItem;
import io.quarkus.artemis.core.deployment.ArtemisJmsRABuildItem;
import io.quarkus.artemis.core.deployment.ShadowRuntimeConfigs;
import io.quarkus.artemis.core.runtime.ArtemisBuildTimeConfig;
import io.quarkus.artemis.core.runtime.ArtemisBuildTimeConfigs;
import io.quarkus.artemis.core.runtime.ArtemisUtil;
import io.quarkus.artemis.core.runtime.health.ArtemisHealthSupport;
import io.quarkus.artemis.core.runtime.health.ArtemisHealthSupportRecorder;
import io.quarkus.artemis.core.runtime.health.ServerLocatorHealthCheck;
Expand All @@ -41,38 +39,20 @@ ArtemisHealthSupportBuildItem healthSupport(
if (!buildTimeConfigs.isHealthEnabled()) {
return null;
}
Set<String> names = new HashSet<>(bootstrap.getConfigurationNames());
Set<String> excludedNames = processConfigs(names, shadowRunTimeConfigs, buildTimeConfigs);
for (ExtraArtemisHealthCheckBuildItem extra : extras) {
String name = extra.getName();
if (!excludedNames.contains(name)) {
names.add(name);
}
}
Set<String> names = Stream
.concat(
bootstrap.getConfigurationNames().stream(),
extras.stream().map(ExtraArtemisHealthCheckBuildItem::getName))
.collect(Collectors.toSet());
syntheticBeanProducer.produce(SyntheticBeanBuildItem
.configure(ArtemisHealthSupport.class)
.supplier(recorder.getArtemisSupportBuilder(names, excludedNames))
.supplier(recorder.getArtemisHealthSupportBuilder(names))
.scope(ApplicationScoped.class)
.defaultBean()
.done());
return new ArtemisHealthSupportBuildItem();
}

private static Set<String> processConfigs(
Set<String> names,
ShadowRuntimeConfigs shadowRunTimeConfigs,
ArtemisBuildTimeConfigs buildTimeConfigs) {
Set<String> excluded = new HashSet<>();
Map<String, ArtemisBuildTimeConfig> allBuildTimeConfigs = buildTimeConfigs.configs();
for (String name : names) {
ArtemisBuildTimeConfig buildTimeConfig = allBuildTimeConfigs.get(name);
if ((ArtemisUtil.isDefault(name) && !shadowRunTimeConfigs.getNames().contains(name) && buildTimeConfig.isEmpty())) {
excluded.add(name);
}
}
return excluded;
}

@SuppressWarnings({ "OptionalUsedAsFieldOrParameterType", "unused" })
@BuildStep
HealthBuildItem healthChecks(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package io.quarkus.artemis.core.runtime;

import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;
import java.util.HashSet;
import java.util.Set;

import jakarta.enterprise.inject.Any;
import jakarta.enterprise.inject.Default;

import io.quarkus.arc.Arc;
import io.quarkus.arc.InstanceHandle;
Expand Down Expand Up @@ -38,15 +38,15 @@ public static void validateIntegrity(
}
}

public static <T> Map<String, T> extractIdentifiers(Class<T> clazz, Set<String> namesToIgnore) {
HashMap<String, T> connectionFactoryNamesFromArc = new HashMap<>();
public static <T> Set<String> extractIdentifiers(Class<T> clazz, Set<String> namesToIgnore) {
Set<String> names = new HashSet<>();
for (InstanceHandle<T> handle : Arc.container().listAll(clazz, Any.Literal.INSTANCE)) {
String name = extractIdentifier(handle);
if (name != null && !namesToIgnore.contains(name)) {
connectionFactoryNamesFromArc.put(name, handle.get());
names.add(name);
}
}
return connectionFactoryNamesFromArc;
return names;
}

private static String extractIdentifier(InstanceHandle<?> handle) {
Expand All @@ -57,4 +57,23 @@ private static String extractIdentifier(InstanceHandle<?> handle) {
}
return null;
}

public static <T> Set<String> getExternalNames(Class<T> type, ArtemisRuntimeConfigs runtimeConfigs,
ArtemisBuildTimeConfigs buildTimeConfigs) {
Set<String> externalNames = new HashSet<>();
if (runtimeConfigs.getHealthExternalEnabled()) {
HashSet<String> namesToIgnore = new HashSet<>(runtimeConfigs.getNames());
namesToIgnore.addAll(buildTimeConfigs.getNames());
externalNames.addAll(ArtemisUtil.extractIdentifiers(type, namesToIgnore));
}
return externalNames;
}

public static Annotation toIdentifier(String name) {
if (isDefault(name)) {
return Default.Literal.INSTANCE;
} else {
return Identifier.Literal.of(name);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,12 @@

public class ArtemisHealthSupport {
private final Set<String> configuredNames;
private final Set<String> excludedNames;

public ArtemisHealthSupport(Set<String> configuredNames, Set<String> excludedNames) {
public ArtemisHealthSupport(Set<String> configuredNames) {
this.configuredNames = configuredNames;
this.excludedNames = excludedNames;
}

public Set<String> getConfiguredNames() {
return configuredNames;
}

public Set<String> getExcludedNames() {
return excludedNames;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@

@Recorder
public class ArtemisHealthSupportRecorder {
public Supplier<ArtemisHealthSupport> getArtemisSupportBuilder(
Set<String> names,
Set<String> excludedNames) {
return () -> new ArtemisHealthSupport(names, excludedNames);
public Supplier<ArtemisHealthSupport> getArtemisHealthSupportBuilder(Set<String> names) {
return () -> new ArtemisHealthSupport(names);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package io.quarkus.artemis.core.runtime.health;

import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Default;
import jakarta.enterprise.inject.Any;
import jakarta.enterprise.inject.Instance;

import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
import org.apache.activemq.artemis.api.core.client.ServerLocator;
Expand All @@ -15,68 +16,34 @@
import org.eclipse.microprofile.health.HealthCheckResponseBuilder;
import org.eclipse.microprofile.health.Readiness;

import io.quarkus.arc.Arc;
import io.quarkus.arc.InstanceHandle;
import io.quarkus.artemis.core.runtime.ArtemisBuildTimeConfigs;
import io.quarkus.artemis.core.runtime.ArtemisRuntimeConfigs;
import io.quarkus.artemis.core.runtime.ArtemisUtil;
import io.smallrye.common.annotation.Identifier;

@Readiness
@ApplicationScoped
public class ServerLocatorHealthCheck implements HealthCheck {
private final HashMap<String, ServerLocator> serverLocators = new HashMap<>();
private final Instance<ServerLocator> serverLocators;
private final Set<String> serverLocatorNames;

public ServerLocatorHealthCheck(
ArtemisRuntimeConfigs runtimeConfigs,
ArtemisBuildTimeConfigs buildTimeConfigs,
@SuppressWarnings("CdiInjectionPointsInspection") ArtemisHealthSupport support) {
HashSet<String> includedNames = new HashSet<>(support.getConfiguredNames());
includedNames.removeAll(support.getExcludedNames());
processKnownBeans(runtimeConfigs, includedNames);
processArcBeans(runtimeConfigs, buildTimeConfigs);
}

private void processKnownBeans(ArtemisRuntimeConfigs runtimeConfigs, HashSet<String> includedNames) {
for (String name : includedNames) {
if (runtimeConfigs.configs().get(name).isHealthInclude()) {
Annotation identifier;
if (ArtemisUtil.isDefault(name)) {
identifier = Default.Literal.INSTANCE;
} else {
identifier = Identifier.Literal.of(name);
}
ServerLocator locator;
try (InstanceHandle<ServerLocator> handle = Arc.container().instance(ServerLocator.class, identifier)) {
locator = handle.get();
}
if (locator != null) {
serverLocators.put(name, locator);
}
}
}
}

private void processArcBeans(ArtemisRuntimeConfigs runtimeConfigs, ArtemisBuildTimeConfigs buildTimeConfigs) {
if (runtimeConfigs.getHealthExternalEnabled()) {
HashSet<String> namesToIgnore = new HashSet<>(runtimeConfigs.configs().keySet());
namesToIgnore.addAll(buildTimeConfigs.configs().keySet());
Map<String, ServerLocator> locatorNamesFromArc = ArtemisUtil.extractIdentifiers(ServerLocator.class, namesToIgnore);
for (var entry : locatorNamesFromArc.entrySet()) {
ServerLocator locator = entry.getValue();
if (locator != null) {
serverLocators.put(entry.getKey(), locator);
}
}
}
@SuppressWarnings("CdiInjectionPointsInspection") ArtemisHealthSupport support,
@Any Instance<ServerLocator> serverLocators) {
this.serverLocators = serverLocators;
serverLocatorNames = support.getConfiguredNames().stream()
.filter(name -> runtimeConfigs.configs().get(name).isHealthInclude())
.collect(Collectors.toCollection(HashSet::new));
serverLocatorNames.addAll(ArtemisUtil.getExternalNames(ServerLocator.class, runtimeConfigs, buildTimeConfigs));
}

@Override
public HealthCheckResponse call() {
HealthCheckResponseBuilder builder = HealthCheckResponse.named("Artemis Core health check").up();
for (var entry : serverLocators.entrySet()) {
String name = entry.getKey();
try (ClientSessionFactory ignored = entry.getValue().createSessionFactory()) {
for (String name : serverLocatorNames) {
Annotation identifier = ArtemisUtil.toIdentifier(name);
try (ClientSessionFactory ignored = serverLocators.select(identifier).get().createSessionFactory()) {
builder.withData(name, "UP");
} catch (Exception e) {
builder.withData(name, "DOWN").down();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package io.quarkus.artemis.jms.runtime.health;

import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Default;
import jakarta.enterprise.inject.Any;
import jakarta.enterprise.inject.Instance;
import jakarta.jms.Connection;
import jakarta.jms.ConnectionFactory;

Expand All @@ -15,70 +16,35 @@
import org.eclipse.microprofile.health.HealthCheckResponseBuilder;
import org.eclipse.microprofile.health.Readiness;

import io.quarkus.arc.Arc;
import io.quarkus.arc.InstanceHandle;
import io.quarkus.artemis.core.runtime.ArtemisBuildTimeConfigs;
import io.quarkus.artemis.core.runtime.ArtemisRuntimeConfigs;
import io.quarkus.artemis.core.runtime.ArtemisUtil;
import io.quarkus.artemis.core.runtime.health.ArtemisHealthSupport;
import io.smallrye.common.annotation.Identifier;

@Readiness
@ApplicationScoped
public class ConnectionFactoryHealthCheck implements HealthCheck {
private final HashMap<String, ConnectionFactory> connectionFactories = new HashMap<>();
private final Instance<ConnectionFactory> connectionFactories;
private final Set<String> connectionFactoryNames;

public ConnectionFactoryHealthCheck(
ArtemisRuntimeConfigs runtimeConfigs,
ArtemisBuildTimeConfigs buildTimeConfigs,
@SuppressWarnings("CdiInjectionPointsInspection") ArtemisHealthSupport support) {
HashSet<String> includedNames = new HashSet<>(support.getConfiguredNames());
includedNames.removeAll(support.getExcludedNames());
processKnownBeans(runtimeConfigs, includedNames);
processArcBeans(runtimeConfigs, buildTimeConfigs);
}

private void processKnownBeans(ArtemisRuntimeConfigs runtimeConfigs, HashSet<String> includedNames) {
for (String name : includedNames) {
if (runtimeConfigs.configs().get(name).isHealthInclude()) {
Annotation identifier;
if (ArtemisUtil.isDefault(name)) {
identifier = Default.Literal.INSTANCE;
} else {
identifier = Identifier.Literal.of(name);
}
ConnectionFactory connectionFactory;
try (InstanceHandle<ConnectionFactory> handle = Arc.container().instance(ConnectionFactory.class, identifier)) {
connectionFactory = handle.get();
}
if (connectionFactory != null) {
connectionFactories.put(name, connectionFactory);
}
}
}
}

private void processArcBeans(ArtemisRuntimeConfigs runtimeConfigs, ArtemisBuildTimeConfigs buildTimeConfigs) {
if (runtimeConfigs.getHealthExternalEnabled()) {
HashSet<String> namesToIgnore = new HashSet<>(runtimeConfigs.getNames());
namesToIgnore.addAll(buildTimeConfigs.getNames());
Map<String, ConnectionFactory> connectionFactoryNamesFromArc = ArtemisUtil
.extractIdentifiers(ConnectionFactory.class, namesToIgnore);
for (var entry : connectionFactoryNamesFromArc.entrySet()) {
ConnectionFactory connectionFactory = entry.getValue();
if (connectionFactory != null) {
connectionFactories.put(entry.getKey(), connectionFactory);
}
}
}
@SuppressWarnings("CdiInjectionPointsInspection") ArtemisHealthSupport support,
@Any Instance<ConnectionFactory> connectionFactories) {
this.connectionFactories = connectionFactories;
connectionFactoryNames = support.getConfiguredNames().stream()
.filter(name -> runtimeConfigs.configs().get(name).isHealthInclude())
.collect(Collectors.toCollection(HashSet::new));
connectionFactoryNames.addAll(ArtemisUtil.getExternalNames(ConnectionFactory.class, runtimeConfigs, buildTimeConfigs));
}

@Override
public HealthCheckResponse call() {
HealthCheckResponseBuilder builder = HealthCheckResponse.named("Artemis JMS health check").up();
for (var entry : connectionFactories.entrySet()) {
String name = entry.getKey();
try (Connection ignored = entry.getValue().createConnection()) {
for (String name : connectionFactoryNames) {
Annotation identifier = ArtemisUtil.toIdentifier(name);
try (Connection ignored = connectionFactories.select(identifier).get().createConnection()) {
builder.withData(name, "UP");
} catch (Exception e) {
builder.withData(name, "DOWN").down();
Expand Down
Loading

0 comments on commit 480f18b

Please sign in to comment.