Skip to content

Commit

Permalink
Properly test existence of classes in micrometer extension
Browse files Browse the repository at this point in the history
The way things were being done previously less to
us leaking the Deployment ClassLoader

Additionally, make changes so the extensions follows
some of the practices that others use

Fixes: quarkusio#42355
  • Loading branch information
geoand committed Aug 7, 2024
1 parent b3e6085 commit aec3cbb
Show file tree
Hide file tree
Showing 17 changed files with 137 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,23 +77,25 @@ public class MicrometerProcessor {
private static final DotName METER_TAG_SUPPORT = DotName.createSimple(MeterTagsSupport.class.getName());

public static class MicrometerEnabled implements BooleanSupplier {
MicrometerConfig mConfig;
private final MicrometerConfig mConfig;

public MicrometerEnabled(MicrometerConfig mConfig) {
this.mConfig = mConfig;
}

public boolean getAsBoolean() {
return mConfig.enabled;
}
}

MicrometerConfig mConfig;

@BuildStep(onlyIfNot = PrometheusRegistryProcessor.PrometheusEnabled.class)
MetricsCapabilityBuildItem metricsCapabilityBuildItem() {
return new MetricsCapabilityBuildItem(MetricsFactory.MICROMETER::equals,
null);
}

@BuildStep(onlyIf = { PrometheusRegistryProcessor.PrometheusEnabled.class })
MetricsCapabilityBuildItem metricsCapabilityPrometheusBuildItem(
MetricsCapabilityBuildItem metricsCapabilityPrometheusBuildItem(MicrometerConfig mConfig,
NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem) {
return new MetricsCapabilityBuildItem(MetricsFactory.MICROMETER::equals,
nonApplicationRootPathBuildItem.resolvePath(mConfig.export.prometheus.path));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,34 @@

import io.micrometer.core.instrument.MeterRegistry;
import io.quarkus.builder.item.MultiBuildItem;
import io.quarkus.micrometer.runtime.MicrometerRecorder;

@SuppressWarnings("unchecked")
public final class MicrometerRegistryProviderBuildItem extends MultiBuildItem {

final Class<? extends MeterRegistry> clazz;
final String registryClassName;

@Deprecated(forRemoval = true)
public MicrometerRegistryProviderBuildItem(Class<?> providedRegistryClass) {
this.clazz = (Class<? extends MeterRegistry>) providedRegistryClass;
this.registryClassName = providedRegistryClass.getName();
}

public MicrometerRegistryProviderBuildItem(String registryClassName) {
this.clazz = (Class<? extends MeterRegistry>) MicrometerRecorder.getClassForName(registryClassName);
this.registryClassName = registryClassName;
}

public Class<? extends MeterRegistry> getRegistryClass() {
return clazz;
try {
return (Class<? extends MeterRegistry>) Class.forName(registryClassName, false,
Thread.currentThread().getContextClassLoader());
} catch (ClassNotFoundException e) {
throw new IllegalStateException(e);
}
}

@Override
public String toString() {
return "MicrometerRegistryProviderBuildItem{"
+ clazz
+ registryClassName
+ '}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ public class GrpcBinderProcessor {
static final String SERVER_INTERCEPTOR = "io.grpc.ServerInterceptor";

static class GrpcClientSupportEnabled implements BooleanSupplier {
MicrometerConfig mConfig;
private final MicrometerConfig mConfig;

GrpcClientSupportEnabled(MicrometerConfig mConfig) {
this.mConfig = mConfig;
}

public boolean getAsBoolean() {
return QuarkusClassLoader.isClassPresentAtRuntime(CLIENT_INTERCEPTOR)
Expand All @@ -32,7 +36,11 @@ public boolean getAsBoolean() {
}

static class GrpcServerSupportEnabled implements BooleanSupplier {
MicrometerConfig mConfig;
private final MicrometerConfig mConfig;

GrpcServerSupportEnabled(MicrometerConfig mConfig) {
this.mConfig = mConfig;
}

public boolean getAsBoolean() {
return QuarkusClassLoader.isClassPresentAtRuntime(SERVER_INTERCEPTOR)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ public class HttpBinderProcessor {
private static final String REST_CLIENT_METRICS_FILTER = "io.quarkus.micrometer.runtime.binder.RestClientMetricsFilter";

static class HttpServerBinderEnabled implements BooleanSupplier {
MicrometerConfig mConfig;
private final MicrometerConfig mConfig;

HttpServerBinderEnabled(MicrometerConfig mConfig) {
this.mConfig = mConfig;
}

public boolean getAsBoolean() {
return mConfig.checkBinderEnabledWithDefault(mConfig.binder.vertx)
Expand All @@ -48,7 +52,11 @@ public boolean getAsBoolean() {
}

static class HttpClientBinderEnabled implements BooleanSupplier {
MicrometerConfig mConfig;
private final MicrometerConfig mConfig;

HttpClientBinderEnabled(MicrometerConfig mConfig) {
this.mConfig = mConfig;
}

public boolean getAsBoolean() {
return QuarkusClassLoader.isClassPresentAtRuntime(REST_CLIENT_REQUEST_FILTER)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import java.util.function.BooleanSupplier;

import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.bootstrap.classloading.QuarkusClassLoader;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.micrometer.runtime.MicrometerRecorder;
import io.quarkus.micrometer.runtime.config.MicrometerConfig;

/**
Expand All @@ -14,28 +14,32 @@
*/
public class KafkaBinderProcessor {
static final String KAFKA_CONSUMER_CLASS_NAME = "org.apache.kafka.clients.consumer.Consumer";
static final Class<?> KAFKA_CONSUMER_CLASS_CLASS = MicrometerRecorder.getClassForName(KAFKA_CONSUMER_CLASS_NAME);

static final String KAFKA_STREAMS_CLASS_NAME = "org.apache.kafka.streams.KafkaStreams";
static final Class<?> KAFKA_STREAMS_CLASS_CLASS = MicrometerRecorder.getClassForName(KAFKA_STREAMS_CLASS_NAME);

static final String KAFKA_EVENT_CONSUMER_CLASS_NAME = "io.quarkus.micrometer.runtime.binder.kafka.KafkaEventObserver";

static final String KAFKA_STREAMS_METRICS_PRODUCER_CLASS_NAME = "io.quarkus.micrometer.runtime.binder.kafka.KafkaStreamsEventObserver";

static class KafkaSupportEnabled implements BooleanSupplier {
MicrometerConfig mConfig;
private final MicrometerConfig mConfig;

KafkaSupportEnabled(MicrometerConfig mConfig) {
this.mConfig = mConfig;
}

public boolean getAsBoolean() {
return KAFKA_CONSUMER_CLASS_CLASS != null && mConfig.checkBinderEnabledWithDefault(mConfig.binder.kafka);
return QuarkusClassLoader.isClassPresentAtRuntime(KAFKA_CONSUMER_CLASS_NAME)
&& mConfig.checkBinderEnabledWithDefault(mConfig.binder.kafka);
}
}

static class KafkaStreamsSupportEnabled implements BooleanSupplier {
MicrometerConfig mConfig;

public boolean getAsBoolean() {
return KAFKA_STREAMS_CLASS_CLASS != null && mConfig.checkBinderEnabledWithDefault(mConfig.binder.kafka);
return QuarkusClassLoader.isClassPresentAtRuntime(KAFKA_STREAMS_CLASS_NAME)
&& mConfig.checkBinderEnabledWithDefault(mConfig.binder.kafka);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.quarkus.micrometer.deployment.binder;

import static io.quarkus.bootstrap.classloading.QuarkusClassLoader.isClassPresentAtRuntime;

import java.util.function.BooleanSupplier;

import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
Expand All @@ -8,7 +10,6 @@
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import io.quarkus.micrometer.runtime.MicrometerRecorder;
import io.quarkus.micrometer.runtime.binder.netty.NettyMetricsProvider;
import io.quarkus.micrometer.runtime.binder.netty.ReactiveNettyMetricsProvider;
import io.quarkus.micrometer.runtime.binder.netty.VertxNettyAllocatorMetricsProvider;
Expand All @@ -22,97 +23,106 @@
*/
public class NettyBinderProcessor {
static final String NETTY_ALLOCATOR_METRICS_NAME = "io.micrometer.core.instrument.binder.netty4.NettyAllocatorMetrics";
static final Class<?> NETTY_ALLOCATOR_METRICS_CLASS = MicrometerRecorder.getClassForName(NETTY_ALLOCATOR_METRICS_NAME);

static final String NETTY_EVENT_EXECUTOR_METRICS_NAME = "io.micrometer.core.instrument.binder.netty4.NettyEventExecutorMetrics";
static final Class<?> NETTY_EVENT_EXECUTOR_METRICS_CLASS = MicrometerRecorder
.getClassForName(NETTY_EVENT_EXECUTOR_METRICS_NAME);

static final String NETTY_BYTE_BUF_ALLOCATOR_NAME = "io.netty.buffer.PooledByteBufAllocator";
static final Class<?> NETTY_BYTE_BUF_ALLOCATOR_CLASS = MicrometerRecorder.getClassForName(NETTY_BYTE_BUF_ALLOCATOR_NAME);

static final String VERTX_BYTE_BUF_ALLOCATOR_NAME = "io.vertx.core.buffer.impl.VertxByteBufAllocator";
static final Class<?> VERTX_BYTE_BUF_ALLOCATOR_CLASS = MicrometerRecorder.getClassForName(VERTX_BYTE_BUF_ALLOCATOR_NAME);

static final String REACTIVE_USAGE_NAME = "org.jboss.resteasy.reactive.client.impl.multipart.QuarkusMultipartFormUpload";
static final Class<?> REACTIVE_USAGE_CLASS = MicrometerRecorder.getClassForName(REACTIVE_USAGE_NAME);

static final String VERTX_NAME = "io.vertx.core.Vertx";
static final Class<?> VERTX_CLASS = MicrometerRecorder.getClassForName(VERTX_NAME);

private static abstract class AbstractSupportEnabled implements BooleanSupplier {
abstract MicrometerConfig getMicrometerConfig();

Class<?> metricsClass() {
return NETTY_ALLOCATOR_METRICS_CLASS;
String metricsClass() {
return NETTY_ALLOCATOR_METRICS_NAME;
}

abstract Class<?> getCheckClass();
abstract String getCheckClass();

public boolean getAsBoolean() {
return metricsClass() != null && getCheckClass() != null
return isClassPresentAtRuntime(metricsClass()) && isClassPresentAtRuntime(getCheckClass())
&& getMicrometerConfig().checkBinderEnabledWithDefault(getMicrometerConfig().binder.netty);
}
}

static class NettySupportEnabled extends AbstractSupportEnabled {
MicrometerConfig mConfig;
private final MicrometerConfig mConfig;

NettySupportEnabled(MicrometerConfig mConfig) {
this.mConfig = mConfig;
}

@Override
MicrometerConfig getMicrometerConfig() {
return mConfig;
}

@Override
Class<?> getCheckClass() {
return NETTY_BYTE_BUF_ALLOCATOR_CLASS;
String getCheckClass() {
return NETTY_BYTE_BUF_ALLOCATOR_NAME;
}
}

static class VertxAllocatorSupportEnabled extends AbstractSupportEnabled {
MicrometerConfig mConfig;
private final MicrometerConfig mConfig;

VertxAllocatorSupportEnabled(MicrometerConfig mConfig) {
this.mConfig = mConfig;
}

@Override
MicrometerConfig getMicrometerConfig() {
return mConfig;
}

@Override
Class<?> getCheckClass() {
return VERTX_BYTE_BUF_ALLOCATOR_CLASS;
String getCheckClass() {
return VERTX_BYTE_BUF_ALLOCATOR_NAME;
}
}

static class VertxEventExecutorSupportEnabled extends AbstractSupportEnabled {
MicrometerConfig mConfig;
private final MicrometerConfig mConfig;

VertxEventExecutorSupportEnabled(MicrometerConfig mConfig) {
this.mConfig = mConfig;
}

@Override
MicrometerConfig getMicrometerConfig() {
return mConfig;
}

@Override
Class<?> metricsClass() {
return NETTY_EVENT_EXECUTOR_METRICS_CLASS;
String metricsClass() {
return NETTY_EVENT_EXECUTOR_METRICS_NAME;
}

@Override
Class<?> getCheckClass() {
return VERTX_CLASS;
String getCheckClass() {
return VERTX_NAME;
}
}

static class ReactiveSupportEnabled extends AbstractSupportEnabled {
MicrometerConfig mConfig;
private final MicrometerConfig mConfig;

ReactiveSupportEnabled(MicrometerConfig mConfig) {
this.mConfig = mConfig;
}

@Override
MicrometerConfig getMicrometerConfig() {
return mConfig;
}

@Override
Class<?> getCheckClass() {
return REACTIVE_USAGE_CLASS;
String getCheckClass() {
return REACTIVE_USAGE_NAME;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,24 @@
import java.util.function.BooleanSupplier;

import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.bootstrap.classloading.QuarkusClassLoader;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.micrometer.runtime.MicrometerRecorder;
import io.quarkus.micrometer.runtime.config.MicrometerConfig;

public class ReactiveMessagingProcessor {

static final String MESSAGE_OBSERVATION_COLLECTOR = "io.smallrye.reactive.messaging.observation.MessageObservationCollector";
static final String METRICS_BEAN_CLASS = "io.quarkus.micrometer.runtime.binder.reactivemessaging.MicrometerObservationCollector";
static final Class<?> MESSAGE_OBSERVATION_COLLECTOR_CLASS = MicrometerRecorder
.getClassForName(MESSAGE_OBSERVATION_COLLECTOR);

static class ReactiveMessagingSupportEnabled implements BooleanSupplier {
MicrometerConfig mConfig;
private final MicrometerConfig mConfig;

ReactiveMessagingSupportEnabled(MicrometerConfig mConfig) {
this.mConfig = mConfig;
}

public boolean getAsBoolean() {
return MESSAGE_OBSERVATION_COLLECTOR_CLASS != null &&
return QuarkusClassLoader.isClassPresentAtRuntime(MESSAGE_OBSERVATION_COLLECTOR) &&
mConfig.checkBinderEnabledWithDefault(mConfig.binder.messaging);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,25 @@
import java.util.function.BooleanSupplier;

import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.bootstrap.classloading.QuarkusClassLoader;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.micrometer.runtime.MicrometerRecorder;
import io.quarkus.micrometer.runtime.config.MicrometerConfig;

public class RedisBinderProcessor {

static final String OBSERVABLE_CLIENT = "io.quarkus.redis.runtime.client.ObservableRedis";
static final String METRICS_BEAN_CLASS = "io.quarkus.micrometer.runtime.binder.redis.RedisMetricsBean";

static final Class<?> OBSERVABLE_CLIENT_CLASS = MicrometerRecorder.getClassForName(OBSERVABLE_CLIENT);

static class RedisMetricsSupportEnabled implements BooleanSupplier {
MicrometerConfig mConfig;
private final MicrometerConfig mConfig;

RedisMetricsSupportEnabled(MicrometerConfig mConfig) {
this.mConfig = mConfig;
}

public boolean getAsBoolean() {
return OBSERVABLE_CLIENT_CLASS != null && mConfig.checkBinderEnabledWithDefault(mConfig.binder.redis);
return QuarkusClassLoader.isClassPresentAtRuntime(OBSERVABLE_CLIENT)
&& mConfig.checkBinderEnabledWithDefault(mConfig.binder.redis);
}
}

Expand Down
Loading

0 comments on commit aec3cbb

Please sign in to comment.