Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use constants for Vert.x web route order marks #35917

Merged
merged 2 commits into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions docs/src/main/asciidoc/http-reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -590,3 +590,30 @@ link:https://undertow.io/undertow-docs/undertow-docs-2.0.0/index.html#predicates
=== web.xml

If you are using a `web.xml` file as your configuration file, you can place it in the `src/main/resources/META-INF` directory.

=== Built-in route order values

Route order values are the values that are specified via Vert.x route `io.vertx.ext.web.Route.order(int)` function.

Quarkus registers a couple of routes with specific order values.
The constants are defined in the `io.quarkus.vertx.http.runtime.RouteConstants` class and listed in the table below.
A custom route should define the order of value 20000 or higher so that it does not interfere with the functionality provided by Quarkus and extensions.

Route order constants defined in `io.quarkus.vertx.http.runtime.RouteConstants` and known extensions:

[cols="1,1,3"]
|===
| Route order value| Constant name| Origin
| `Integer.MIN_VALUE` | `ROUTE_ORDER_ACCESS_LOG_HANDLER` | Access-log handler, if enabled in the configuration.
| `Integer.MIN_VALUE` | `ROUTE_ORDER_RECORD_START_TIME` | Handler adding the start-time, if enabled in the configuration.
| `Integer.MIN_VALUE` | `ROUTE_ORDER_HOT_REPLACEMENT` | -replacement body handler.
| `Integer.MIN_VALUE` | `ROUTE_ORDER_BODY_HANDLER_MANAGEMENT` | Body handler for the management router.
| `Integer.MIN_VALUE` | `ROUTE_ORDER_HEADERS` | Handlers that add headers specified in the configuration.
| `Integer.MIN_VALUE` | `ROUTE_ORDER_CORS_MANAGEMENT` | CORS-Origin handler of the management router.
| `Integer.MIN_VALUE + 1` | `ROUTE_ORDER_BODY_HANDLER` | Body handler.
| `-2` | `ROUTE_ORDER_UPLOAD_LIMIT` | Route that enforces the upload body size limit.
| `0` | `ROUTE_ORDER_COMPRESSION` | Compression handler.
| `1000` | `ROUTE_ORDER_BEFORE_DEFAULT` | Route with priority over the default route (add an offset from this value).
| `10000` | `ROUTE_ORDER_DEFAULT` | Default route order (i.e. Static Resources, Servlet).
| `20000` | `ROUTE_ORDER_AFTER_DEFAULT` | Route without priority over the default route (add an offset from this value)
|===
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
import io.quarkus.vertx.http.deployment.RequireVirtualHttpBuildItem;
import io.quarkus.vertx.http.deployment.RouteBuildItem;
import io.quarkus.vertx.http.runtime.HttpBuildTimeConfig;
import io.quarkus.vertx.http.runtime.VertxHttpRecorder;
import io.quarkus.vertx.http.runtime.RouteConstants;
import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;

Expand Down Expand Up @@ -136,7 +136,7 @@ public void boot(ShutdownContextBuildItem shutdown,
routes.produce(
RouteBuildItem.builder()
.orderedRoute(standalone.deploymentRootPath,
VertxHttpRecorder.AFTER_DEFAULT_ROUTE_ORDER_MARK + REST_ROUTE_ORDER_OFFSET)
RouteConstants.ROUTE_ORDER_AFTER_DEFAULT + REST_ROUTE_ORDER_OFFSET)
.handler(handler).build());
String matchPath = standalone.deploymentRootPath;
if (matchPath.endsWith("/")) {
Expand All @@ -146,7 +146,7 @@ public void boot(ShutdownContextBuildItem shutdown,
}
// Match paths that begin with the deployment path
routes.produce(RouteBuildItem.builder()
.orderedRoute(matchPath, VertxHttpRecorder.AFTER_DEFAULT_ROUTE_ORDER_MARK + REST_ROUTE_ORDER_OFFSET)
.orderedRoute(matchPath, RouteConstants.ROUTE_ORDER_AFTER_DEFAULT + REST_ROUTE_ORDER_OFFSET)
.handler(handler).build());

recorder.start(shutdown, requireVirtual.isPresent());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@
import io.quarkus.vertx.http.deployment.FilterBuildItem;
import io.quarkus.vertx.http.deployment.RouteBuildItem;
import io.quarkus.vertx.http.runtime.HttpBuildTimeConfig;
import io.quarkus.vertx.http.runtime.VertxHttpRecorder;
import io.quarkus.vertx.http.runtime.RouteConstants;
import io.vertx.core.Handler;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
Expand Down Expand Up @@ -1251,11 +1251,11 @@ public void setupDeployment(BeanContainerBuildItem beanContainerBuildItem,
.produce(new ResteasyReactiveDeploymentInfoBuildItem(deploymentInfo));

boolean servletPresent = false;
int order = VertxHttpRecorder.AFTER_DEFAULT_ROUTE_ORDER_MARK + REST_ROUTE_ORDER_OFFSET;
int order = RouteConstants.ROUTE_ORDER_AFTER_DEFAULT + REST_ROUTE_ORDER_OFFSET;
if (capabilities.isPresent("io.quarkus.servlet")) {
//if servlet is present we run RR before the default route
//otherwise we run after it
order = VertxHttpRecorder.BEFORE_DEFAULT_ROUTE_ORDER_MARK + REST_ROUTE_ORDER_OFFSET;
order = RouteConstants.ROUTE_ORDER_BEFORE_DEFAULT + REST_ROUTE_ORDER_OFFSET;
servletPresent = true;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package io.quarkus.vertx.http.runtime;

/**
* Route order value constants used in Quarkus, update {@code reactive-routes.adoc} when changing this class.
*/
@SuppressWarnings("JavadocDeclaration")
public final class RouteConstants {
private RouteConstants() {
}

/**
* Order value ({@value #ROUTE_ORDER_ACCESS_LOG_HANDLER}) for the access-log handler, if enabled in the configuration.
*/
public static final int ROUTE_ORDER_ACCESS_LOG_HANDLER = Integer.MIN_VALUE;
/**
* Order value ({@value #ROUTE_ORDER_RECORD_START_TIME}) for the handler adding the start-time, if enabled in the
* configuration.
*/
public static final int ROUTE_ORDER_RECORD_START_TIME = Integer.MIN_VALUE;
/**
* Order value ({@value #ROUTE_ORDER_HOT_REPLACEMENT}) for the hot-replacement body handler.
*/
public static final int ROUTE_ORDER_HOT_REPLACEMENT = Integer.MIN_VALUE;
/**
* Order value ({@value #ROUTE_ORDER_BODY_HANDLER_MANAGEMENT}) for the body handler for the management router.
*/
public static final int ROUTE_ORDER_BODY_HANDLER_MANAGEMENT = Integer.MIN_VALUE;
/**
* Order value ({@value #ROUTE_ORDER_HEADERS}) for the handlers that add headers specified in the configuration.
*/
public static final int ROUTE_ORDER_HEADERS = Integer.MIN_VALUE;
/**
* Order value ({@value #ROUTE_ORDER_CORS_MANAGEMENT}) for the CORS-Origin handler of the management router.
*/
public static final int ROUTE_ORDER_CORS_MANAGEMENT = Integer.MIN_VALUE;
/**
* Order value ({@value #ROUTE_ORDER_BODY_HANDLER}) for the body handler.
*/
public static final int ROUTE_ORDER_BODY_HANDLER = Integer.MIN_VALUE + 1;
/**
* Order value ({@value #ROUTE_ORDER_UPLOAD_LIMIT}) for the route that enforces the upload body size limit.
*/
public static final int ROUTE_ORDER_UPLOAD_LIMIT = -2;
/**
* Order value ({@value #ROUTE_ORDER_COMPRESSION}) for the compression handler.
*/
public static final int ROUTE_ORDER_COMPRESSION = 0;
/**
* Order value ({@value #ROUTE_ORDER_BEFORE_DEFAULT}) for route with priority over the default route (add an offset from
* this value)
*/
public static final int ROUTE_ORDER_BEFORE_DEFAULT = 1_000;
/**
* Default route order (i.e. Static Resources, Servlet): ({@value #ROUTE_ORDER_DEFAULT})
*/
public static final int ROUTE_ORDER_DEFAULT = 10_000;
/**
* Order value ({@value #ROUTE_ORDER_AFTER_DEFAULT}) for route without priority over the default route (add an offset
* from this value)
*/
public static final int ROUTE_ORDER_AFTER_DEFAULT = 20_000;
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,21 +117,6 @@ public class VertxHttpRecorder {

private static final String DISABLE_WEBSOCKETS_PROP_NAME = "vertx.disableWebsockets";

/**
* Order mark for route with priority over the default route (add an offset from this mark)
**/
public static final int BEFORE_DEFAULT_ROUTE_ORDER_MARK = 1_000;

/**
* Default route order (i.e. Static Resources, Servlet)
**/
public static final int DEFAULT_ROUTE_ORDER = 10_000;

/**
* Order mark for route without priority over the default route (add an offset from this mark)
**/
public static final int AFTER_DEFAULT_ROUTE_ORDER_MARK = 20_000;

private static final Logger LOGGER = Logger.getLogger(VertxHttpRecorder.class.getName());

private static volatile Handler<RoutingContext> hotReplacementHandler;
Expand Down Expand Up @@ -273,7 +258,7 @@ public static void startServerAfterFailedStart() {
}
Router router = Router.router(vertx);
if (hotReplacementHandler != null) {
router.route().order(Integer.MIN_VALUE).blockingHandler(hotReplacementHandler);
router.route().order(RouteConstants.ROUTE_ORDER_HOT_REPLACEMENT).blockingHandler(hotReplacementHandler);
}

Handler<HttpServerRequest> root = router;
Expand Down Expand Up @@ -402,7 +387,7 @@ public void finalizeRouter(BeanContainer container, Consumer<Route> defaultRoute
}

if (defaultRouteHandler != null) {
defaultRouteHandler.accept(httpRouteRouter.route().order(DEFAULT_ROUTE_ORDER));
defaultRouteHandler.accept(httpRouteRouter.route().order(RouteConstants.ROUTE_ORDER_DEFAULT));
}

applyCompression(httpBuildTimeConfig.enableCompression, httpRouteRouter);
Expand All @@ -412,7 +397,7 @@ public void finalizeRouter(BeanContainer container, Consumer<Route> defaultRoute
if (requireBodyHandler) {
//if this is set then everything needs the body handler installed
//TODO: config etc
httpRouteRouter.route().order(Integer.MIN_VALUE + 1).handler(new Handler<RoutingContext>() {
httpRouteRouter.route().order(RouteConstants.ROUTE_ORDER_BODY_HANDLER).handler(new Handler<RoutingContext>() {
@Override
public void handle(RoutingContext routingContext) {
routingContext.request().resume();
Expand All @@ -433,13 +418,14 @@ public void handle(RoutingContext routingContext) {
if (hotReplacementHandler != null) {
//recorders are always executed in the current CL
ClassLoader currentCl = Thread.currentThread().getContextClassLoader();
httpRouteRouter.route().order(Integer.MIN_VALUE).handler(new Handler<RoutingContext>() {
@Override
public void handle(RoutingContext event) {
Thread.currentThread().setContextClassLoader(currentCl);
hotReplacementHandler.handle(event);
}
});
httpRouteRouter.route().order(RouteConstants.ROUTE_ORDER_HOT_REPLACEMENT)
.handler(new Handler<RoutingContext>() {
@Override
public void handle(RoutingContext event) {
Thread.currentThread().setContextClassLoader(currentCl);
hotReplacementHandler.handle(event);
}
});
}
root = httpRouteRouter;
} else {
Expand All @@ -449,7 +435,7 @@ public void handle(RoutingContext event) {

if (hotReplacementHandler != null) {
ClassLoader currentCl = Thread.currentThread().getContextClassLoader();
mainRouter.route().order(Integer.MIN_VALUE).handler(new Handler<RoutingContext>() {
mainRouter.route().order(RouteConstants.ROUTE_ORDER_HOT_REPLACEMENT).handler(new Handler<RoutingContext>() {
@Override
public void handle(RoutingContext event) {
Thread.currentThread().setContextClassLoader(currentCl);
Expand Down Expand Up @@ -484,15 +470,16 @@ public void handle(RoutingContext event) {
AccessLogHandler handler = new AccessLogHandler(receiver, accessLog.pattern, getClass().getClassLoader(),
accessLog.excludePattern);
if (rootPath.equals("/") || nonRootPath.equals("/")) {
mainRouterRuntimeValue.orElse(httpRouterRuntimeValue).getValue().route().order(Integer.MIN_VALUE)
mainRouterRuntimeValue.orElse(httpRouterRuntimeValue).getValue().route()
.order(RouteConstants.ROUTE_ORDER_ACCESS_LOG_HANDLER)
.handler(handler);
} else if (nonRootPath.startsWith(rootPath)) {
httpRouteRouter.route().order(Integer.MIN_VALUE).handler(handler);
httpRouteRouter.route().order(RouteConstants.ROUTE_ORDER_ACCESS_LOG_HANDLER).handler(handler);
} else if (rootPath.startsWith(nonRootPath)) {
frameworkRouter.getValue().route().order(Integer.MIN_VALUE).handler(handler);
frameworkRouter.getValue().route().order(RouteConstants.ROUTE_ORDER_ACCESS_LOG_HANDLER).handler(handler);
} else {
httpRouteRouter.route().order(Integer.MIN_VALUE).handler(handler);
frameworkRouter.getValue().route().order(Integer.MIN_VALUE).handler(handler);
httpRouteRouter.route().order(RouteConstants.ROUTE_ORDER_ACCESS_LOG_HANDLER).handler(handler);
frameworkRouter.getValue().route().order(RouteConstants.ROUTE_ORDER_ACCESS_LOG_HANDLER).handler(handler);
}

quarkusWrapperNeeded = true;
Expand All @@ -518,7 +505,7 @@ public void handle(HttpServerRequest event) {
Handler<HttpServerRequest> delegate = root;
root = HttpServerCommonHandlers.enforceDuplicatedContext(delegate);
if (httpConfiguration.recordRequestStartTime) {
httpRouteRouter.route().order(Integer.MIN_VALUE).handler(new Handler<RoutingContext>() {
httpRouteRouter.route().order(RouteConstants.ROUTE_ORDER_RECORD_START_TIME).handler(new Handler<RoutingContext>() {
@Override
public void handle(RoutingContext event) {
event.put(REQUEST_START_TIME, System.nanoTime());
Expand All @@ -539,9 +526,10 @@ public void handle(RoutingContext event) {
mr.route().last().failureHandler(
new QuarkusErrorHandler(launchMode.isDevOrTest(), httpConfiguration.unhandledErrorContentTypeDefault));

mr.route().order(Integer.MIN_VALUE).handler(createBodyHandlerForManagementInterface());
mr.route().order(RouteConstants.ROUTE_ORDER_BODY_HANDLER_MANAGEMENT)
.handler(createBodyHandlerForManagementInterface());
// We can use "*" here as the management interface is not expected to be used publicly.
mr.route().order(Integer.MIN_VALUE).handler(CorsHandler.create().addOrigin("*"));
mr.route().order(RouteConstants.ROUTE_ORDER_CORS_MANAGEMENT).handler(CorsHandler.create().addOrigin("*"));

HttpServerCommonHandlers.applyFilters(managementConfiguration.getValue().filter, mr);
for (Filter filter : managementInterfaceFilterList) {
Expand All @@ -562,7 +550,7 @@ public void handle(RoutingContext event) {

private void applyCompression(boolean enableCompression, Router httpRouteRouter) {
if (enableCompression) {
httpRouteRouter.route().order(0).handler(new Handler<RoutingContext>() {
httpRouteRouter.route().order(RouteConstants.ROUTE_ORDER_COMPRESSION).handler(new Handler<RoutingContext>() {
@Override
public void handle(RoutingContext ctx) {
// Add "Content-Encoding: identity" header that disables the compression
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import io.quarkus.vertx.http.runtime.HeaderConfig;
import io.quarkus.vertx.http.runtime.ProxyConfig;
import io.quarkus.vertx.http.runtime.ResumingRequestWrapper;
import io.quarkus.vertx.http.runtime.RouteConstants;
import io.quarkus.vertx.http.runtime.ServerLimitsConfig;
import io.quarkus.vertx.http.runtime.TrustedProxyCheck;
import io.quarkus.vertx.http.runtime.VertxHttpRecorder;
Expand All @@ -33,7 +34,7 @@ public static void enforceMaxBodySize(ServerLimitsConfig limits, Router httpRout
if (limits.maxBodySize.isPresent()) {
long limit = limits.maxBodySize.get().asLongValue();
Long limitObj = limit;
httpRouteRouter.route().order(-2).handler(new Handler<RoutingContext>() {
httpRouteRouter.route().order(RouteConstants.ROUTE_ORDER_UPLOAD_LIMIT).handler(new Handler<RoutingContext>() {
@Override
public void handle(RoutingContext event) {
String lengthString = event.request().headers().get(HttpHeaderNames.CONTENT_LENGTH);
Expand Down Expand Up @@ -150,7 +151,7 @@ public static void applyHeaders(Map<String, HeaderConfig> headers, Router httpRo
var config = entry.getValue();
if (config.methods.isEmpty()) {
httpRouteRouter.route(config.path)
.order(Integer.MIN_VALUE)
.order(RouteConstants.ROUTE_ORDER_HEADERS)
.handler(new Handler<RoutingContext>() {
@Override
public void handle(RoutingContext event) {
Expand All @@ -161,7 +162,7 @@ public void handle(RoutingContext event) {
} else {
for (String method : config.methods.get()) {
httpRouteRouter.route(HttpMethod.valueOf(method.toUpperCase(Locale.ROOT)), config.path)
.order(Integer.MIN_VALUE)
.order(RouteConstants.ROUTE_ORDER_HEADERS)
.handler(new Handler<RoutingContext>() {
@Override
public void handle(RoutingContext event) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import jakarta.enterprise.event.Observes;

import io.quarkus.runtime.StartupEvent;
import io.quarkus.vertx.http.runtime.RouteConstants;
import io.quarkus.vertx.http.runtime.ServerLimitsConfig;
import io.quarkus.vertx.http.runtime.options.HttpServerCommonHandlers;
import io.vertx.core.buffer.Buffer;
Expand All @@ -21,11 +22,12 @@ public class UploadRoute {

/**
* Installs two POST-routes - one that bypasses the body-length limit using {@code order(-3)}
* ({@link HttpServerCommonHandlers#enforceMaxBodySize(ServerLimitsConfig, Router)} uses {@code order(-2)}) and one that
* ({@link HttpServerCommonHandlers#enforceMaxBodySize(ServerLimitsConfig, Router)} uses
* {@value RouteConstants#ROUTE_ORDER_UPLOAD_LIMIT} for {@link io.vertx.ext.web.Route#order(int)}) and one that
* does not bypass body-size enforcement.
*/
void installRoute(@Observes StartupEvent startupEvent, Router router) {
router.post("/unlimited-upload").order(-3).handler(UploadHandler::newRequest);
router.post("/unlimited-upload").order(RouteConstants.ROUTE_ORDER_UPLOAD_LIMIT - 1).handler(UploadHandler::newRequest);
router.post("/limited-upload").handler(UploadHandler::newRequest);
}

Expand Down
Loading