diff --git a/extensions/smallrye-metrics/deployment/pom.xml b/extensions/smallrye-metrics/deployment/pom.xml
index 2ce770d7f44a9..882e931391bd6 100644
--- a/extensions/smallrye-metrics/deployment/pom.xml
+++ b/extensions/smallrye-metrics/deployment/pom.xml
@@ -20,7 +20,7 @@
io.quarkus
- quarkus-undertow-deployment
+ quarkus-vertx-http-deployment
io.quarkus
diff --git a/extensions/smallrye-metrics/deployment/src/main/java/io/quarkus/smallrye/metrics/deployment/SmallRyeMetricsProcessor.java b/extensions/smallrye-metrics/deployment/src/main/java/io/quarkus/smallrye/metrics/deployment/SmallRyeMetricsProcessor.java
index 8fc2d4b23d1a4..62015c3eea35a 100644
--- a/extensions/smallrye-metrics/deployment/src/main/java/io/quarkus/smallrye/metrics/deployment/SmallRyeMetricsProcessor.java
+++ b/extensions/smallrye-metrics/deployment/src/main/java/io/quarkus/smallrye/metrics/deployment/SmallRyeMetricsProcessor.java
@@ -13,6 +13,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.function.Function;
import javax.enterprise.context.Dependent;
@@ -31,6 +32,7 @@
import io.quarkus.arc.deployment.AutoInjectAnnotationBuildItem;
import io.quarkus.arc.deployment.BeanArchiveIndexBuildItem;
import io.quarkus.arc.deployment.BeanContainerBuildItem;
+import io.quarkus.arc.deployment.UnremovableBeanBuildItem;
import io.quarkus.arc.processor.AnnotationsTransformer;
import io.quarkus.arc.processor.BuiltinScope;
import io.quarkus.deployment.annotations.BuildProducer;
@@ -45,8 +47,8 @@
import io.quarkus.smallrye.metrics.deployment.jandex.JandexBeanInfoAdapter;
import io.quarkus.smallrye.metrics.deployment.jandex.JandexMemberInfoAdapter;
import io.quarkus.smallrye.metrics.runtime.SmallRyeMetricsRecorder;
-import io.quarkus.smallrye.metrics.runtime.SmallRyeMetricsServlet;
-import io.quarkus.undertow.deployment.ServletBuildItem;
+import io.quarkus.vertx.http.deployment.RouteBuildItem;
+import io.quarkus.vertx.http.runtime.HandlerType;
import io.smallrye.metrics.MetricProducer;
import io.smallrye.metrics.MetricRegistries;
import io.smallrye.metrics.MetricsRequestHandler;
@@ -57,6 +59,8 @@
import io.smallrye.metrics.interceptors.MetricNameFactory;
import io.smallrye.metrics.interceptors.MetricsInterceptor;
import io.smallrye.metrics.interceptors.TimedInterceptor;
+import io.vertx.ext.web.Route;
+import io.vertx.ext.web.Router;
public class SmallRyeMetricsProcessor {
private static final Logger LOGGER = Logger.getLogger("io.quarkus.smallrye.metrics.deployment.SmallRyeMetricsProcessor");
@@ -65,7 +69,7 @@ public class SmallRyeMetricsProcessor {
static final class SmallRyeMetricsConfig {
/**
- * The path to the metrics Servlet.
+ * The path to the metrics handler.
*/
@ConfigItem(defaultValue = "/metrics")
String path;
@@ -74,16 +78,16 @@ static final class SmallRyeMetricsConfig {
SmallRyeMetricsConfig metrics;
@BuildStep
- ServletBuildItem createServlet() {
- ServletBuildItem servletBuildItem = ServletBuildItem.builder("metrics", SmallRyeMetricsServlet.class.getName())
- .addMapping(metrics.path + (metrics.path.endsWith("/") ? "*" : "/*"))
- .addInitParam("metrics.path", metrics.path)
- .build();
- return servletBuildItem;
+ @Record(STATIC_INIT)
+ void createRoute(BuildProducer routes,
+ SmallRyeMetricsRecorder recorder) {
+ Function route = recorder.route(metrics.path + (metrics.path.endsWith("/") ? "*" : "/*"));
+ routes.produce(new RouteBuildItem(route, recorder.handler(metrics.path), HandlerType.BLOCKING));
}
@BuildStep
- void beans(BuildProducer additionalBeans) {
+ void beans(BuildProducer additionalBeans,
+ BuildProducer unremovableBeans) {
additionalBeans.produce(new AdditionalBeanBuildItem(MetricProducer.class,
MetricNameFactory.class,
MetricRegistries.class,
@@ -92,8 +96,9 @@ void beans(BuildProducer additionalBeans) {
ConcurrentGaugeInterceptor.class,
CountedInterceptor.class,
TimedInterceptor.class,
- MetricsRequestHandler.class,
- SmallRyeMetricsServlet.class));
+ MetricsRequestHandler.class));
+ unremovableBeans.produce(new UnremovableBeanBuildItem(
+ new UnremovableBeanBuildItem.BeanClassNameExclusion(MetricsRequestHandler.class.getName())));
}
@BuildStep
diff --git a/extensions/smallrye-metrics/runtime/pom.xml b/extensions/smallrye-metrics/runtime/pom.xml
index ff3b4e76914f1..2ef21b90fdc92 100644
--- a/extensions/smallrye-metrics/runtime/pom.xml
+++ b/extensions/smallrye-metrics/runtime/pom.xml
@@ -25,7 +25,7 @@
io.quarkus
- quarkus-undertow
+ quarkus-vertx-http
io.quarkus
@@ -35,10 +35,6 @@
io.quarkus
quarkus-jsonp
-
- org.jboss.spec.javax.servlet
- jboss-servlet-api_4.0_spec
-
diff --git a/extensions/smallrye-metrics/runtime/src/main/java/io/quarkus/smallrye/metrics/runtime/SmallRyeMetricsHandler.java b/extensions/smallrye-metrics/runtime/src/main/java/io/quarkus/smallrye/metrics/runtime/SmallRyeMetricsHandler.java
new file mode 100644
index 0000000000000..7a361358b6d0d
--- /dev/null
+++ b/extensions/smallrye-metrics/runtime/src/main/java/io/quarkus/smallrye/metrics/runtime/SmallRyeMetricsHandler.java
@@ -0,0 +1,47 @@
+package io.quarkus.smallrye.metrics.runtime;
+
+import java.io.IOException;
+import java.util.stream.Stream;
+
+import javax.enterprise.inject.spi.CDI;
+
+import org.jboss.logging.Logger;
+
+import io.smallrye.metrics.MetricsRequestHandler;
+import io.vertx.core.Handler;
+import io.vertx.core.buffer.Buffer;
+import io.vertx.core.http.HttpServerRequest;
+import io.vertx.core.http.HttpServerResponse;
+import io.vertx.ext.web.RoutingContext;
+
+public class SmallRyeMetricsHandler implements Handler {
+
+ private String metricsPath;
+
+ private static final Logger LOGGER = Logger.getLogger(SmallRyeMetricsHandler.class.getName());
+
+ public void setMetricsPath(String metricsPath) {
+ this.metricsPath = metricsPath;
+ }
+
+ @Override
+ public void handle(RoutingContext routingContext) {
+ MetricsRequestHandler internalHandler = CDI.current().select(MetricsRequestHandler.class).get();
+ HttpServerResponse response = routingContext.response();
+ HttpServerRequest request = routingContext.request();
+ Stream acceptHeaders = request.headers().getAll("Accept").stream();
+
+ try {
+ internalHandler.handleRequest(request.path(), metricsPath, request.rawMethod(), acceptHeaders,
+ (status, message, headers) -> {
+ response.setStatusCode(status);
+ headers.forEach(response::putHeader);
+ response.end(Buffer.buffer(message));
+ });
+ } catch (IOException e) {
+ response.setStatusCode(503);
+ response.end();
+ LOGGER.error(e);
+ }
+ }
+}
diff --git a/extensions/smallrye-metrics/runtime/src/main/java/io/quarkus/smallrye/metrics/runtime/SmallRyeMetricsRecorder.java b/extensions/smallrye-metrics/runtime/src/main/java/io/quarkus/smallrye/metrics/runtime/SmallRyeMetricsRecorder.java
index fb387f72011fa..b2bf8d7d5262f 100644
--- a/extensions/smallrye-metrics/runtime/src/main/java/io/quarkus/smallrye/metrics/runtime/SmallRyeMetricsRecorder.java
+++ b/extensions/smallrye-metrics/runtime/src/main/java/io/quarkus/smallrye/metrics/runtime/SmallRyeMetricsRecorder.java
@@ -10,6 +10,7 @@
import java.lang.management.ThreadMXBean;
import java.util.ArrayList;
import java.util.List;
+import java.util.function.Function;
import org.eclipse.microprofile.metrics.Metadata;
import org.eclipse.microprofile.metrics.MetricRegistry;
@@ -27,6 +28,8 @@
import io.smallrye.metrics.elementdesc.MemberInfo;
import io.smallrye.metrics.interceptors.MetricResolver;
import io.smallrye.metrics.setup.MetricsMetadata;
+import io.vertx.ext.web.Route;
+import io.vertx.ext.web.Router;
@Recorder
public class SmallRyeMetricsRecorder {
@@ -63,6 +66,21 @@ public class SmallRyeMetricsRecorder {
private static final String MEMORY_USED_HEAP = "memory.usedHeap";
private static final String MEMORY_USED_NON_HEAP = "memory.usedNonHeap";
+ public Function route(String name) {
+ return new Function() {
+ @Override
+ public Route apply(Router router) {
+ return router.route(name);
+ }
+ };
+ }
+
+ public SmallRyeMetricsHandler handler(String metricsPath) {
+ SmallRyeMetricsHandler handler = new SmallRyeMetricsHandler();
+ handler.setMetricsPath(metricsPath);
+ return handler;
+ }
+
public void registerVendorMetrics(ShutdownContext shutdown) {
MetricRegistry registry = MetricRegistries.get(MetricRegistry.Type.VENDOR);
List names = new ArrayList<>();
diff --git a/extensions/smallrye-metrics/runtime/src/main/java/io/quarkus/smallrye/metrics/runtime/SmallRyeMetricsServlet.java b/extensions/smallrye-metrics/runtime/src/main/java/io/quarkus/smallrye/metrics/runtime/SmallRyeMetricsServlet.java
deleted file mode 100644
index dc103a850eedd..0000000000000
--- a/extensions/smallrye-metrics/runtime/src/main/java/io/quarkus/smallrye/metrics/runtime/SmallRyeMetricsServlet.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package io.quarkus.smallrye.metrics.runtime;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.stream.Stream;
-
-import javax.inject.Inject;
-import javax.servlet.annotation.WebServlet;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.microprofile.config.inject.ConfigProperty;
-
-import io.smallrye.metrics.MetricsRequestHandler;
-
-@WebServlet
-public class SmallRyeMetricsServlet extends HttpServlet {
-
- @Inject
- MetricsRequestHandler metricsHandler;
-
- @ConfigProperty(name = "quarkus.servlet.context-path", defaultValue = "/")
- String appContextPath;
-
- // full path where the metrics endpoint resides, by default it's /metrics, but can be /appContextPath/anything
- private String contextPath;
-
- @Override
- public void init() {
- String metricsPath = getInitParameter("metrics.path");
- // add leading / if there isn't one
- String metricPathSanitized = metricsPath.startsWith("/") ? metricsPath : "/" + metricsPath;
- // strip off trailing / if there is
- String appContextPathSanitized = appContextPath.endsWith("/") ? appContextPath.substring(0, appContextPath.length() - 1)
- : appContextPath;
- contextPath = appContextPathSanitized + metricPathSanitized;
- }
-
- @Override
- protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws IOException {
- doGet(req, resp);
- }
-
- @Override
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
- String requestPath = request.getRequestURI();
- String method = request.getMethod();
- Stream acceptHeaders = Collections.list(request.getHeaders("Accept")).stream();
-
- metricsHandler.handleRequest(requestPath, contextPath, method, acceptHeaders, (status, message, headers) -> {
- headers.forEach(response::addHeader);
- response.setStatus(status);
-
- // FIXME: this is a workaround for issue #3673, normally just response.getWriter().write(message) should do
- final int stepSize = 5000;
- if (message.length() < stepSize) {
- response.getWriter().write(message);
- } else {
- // split a string longer than 8192 characters into smaller chunks
- // and feed them one by one to the writer
- // and call flush() in between
- for (int i = 0; i < (message.length() / stepSize) + 1; i++) {
- int start = stepSize * i;
- final int chars = Math.min(stepSize, message.length() - (stepSize * i));
- response.getWriter()
- .write(message.substring(start, start + chars));
- response.getWriter().flush();
- }
- }
- });
- }
-}