Skip to content

Commit

Permalink
Allows Vert.x HTTP Options customization
Browse files Browse the repository at this point in the history
  • Loading branch information
cescoffier committed Jul 19, 2022
1 parent fee39a6 commit b9c3ab4
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.deployment.BeanContainerBuildItem;
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
import io.quarkus.arc.deployment.UnremovableBeanBuildItem;
import io.quarkus.arc.processor.BuiltinScope;
import io.quarkus.bootstrap.classloading.ClassPathElement;
import io.quarkus.bootstrap.classloading.QuarkusClassLoader;
Expand Down Expand Up @@ -46,6 +47,7 @@
import io.quarkus.runtime.shutdown.ShutdownConfig;
import io.quarkus.vertx.core.deployment.CoreVertxBuildItem;
import io.quarkus.vertx.core.deployment.EventLoopCountBuildItem;
import io.quarkus.vertx.http.HttpServerOptionsCustomizer;
import io.quarkus.vertx.http.deployment.devmode.HttpRemoteDevClientProvider;
import io.quarkus.vertx.http.deployment.devmode.NotFoundPageDisplayableEndpointBuildItem;
import io.quarkus.vertx.http.deployment.spi.FrameworkEndpointsBuildItem;
Expand Down Expand Up @@ -113,6 +115,11 @@ AdditionalBeanBuildItem additionalBeans() {
.build();
}

@BuildStep
UnremovableBeanBuildItem shouldNotRemoveHttpServerOptionsCustomizers() {
return UnremovableBeanBuildItem.beanTypes(HttpServerOptionsCustomizer.class);
}

/**
* Workaround for https://github.com/quarkusio/quarkus/issues/4720 by filtering Vertx multiple instance warning in dev
* mode.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package io.quarkus.vertx.http.customizers;

import java.util.concurrent.atomic.AtomicInteger;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;
import javax.inject.Inject;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;
import io.quarkus.vertx.http.HttpServerOptionsCustomizer;
import io.restassured.RestAssured;
import io.vertx.core.http.HttpServerOptions;
import io.vertx.mutiny.ext.web.Router;

public class HttpServerOptionsCustomizerTest {

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar
.addClasses(MyBean.class, MyCustomizer.class));

@Inject
MyCustomizer customizer;

@Test
void test() {
Assertions.assertThat(customizer.count()).isEqualTo(1);
Assertions.assertThat(RestAssured.get("http://localhost:9998").body().asString()).isEqualTo("hello");
}

@ApplicationScoped
public static class MyBean {

public void init(@Observes Router router) {
router.get().handler(rc -> rc.endAndForget("hello"));
}

}

@ApplicationScoped
public static class MyCustomizer implements HttpServerOptionsCustomizer {

AtomicInteger count = new AtomicInteger();

@Override
public void customizeHttpServer(HttpServerOptions options) {
count.incrementAndGet();
options.setPort(9998);
}

@Override
public void customizeHttpsServer(HttpServerOptions options) {
count.incrementAndGet();
}

@Override
public void customizeDomainSocketServer(HttpServerOptions options) {
count.incrementAndGet();
}

public int count() {
return count.get();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package io.quarkus.vertx.http;

import io.vertx.core.http.HttpServerOptions;

/**
* Interface exposed by beans willing to customizing the HTTP server options.
* <p>
* This interface is composed of three methods allowing the customization of the different servers: HTTP, HTTPS and
* domain socket.
* <p>
* The passed {@link HttpServerOptions} must be customized in the body of the implementation. The default implementations
* are no-op.
*/
public interface HttpServerOptionsCustomizer {

/**
* Allows customizing the HTTP server options.
*/
default void customizeHttpServer(HttpServerOptions options) {
// NO-OP
}

/**
* Allows customizing the HTTPS server options.
*/
default void customizeHttpsServer(HttpServerOptions options) {
// NO-OP
}

/**
* Allows customizing the server listening on a domain socket if any.
*/
default void customizeDomainSocketServer(HttpServerOptions options) {
// NO-OP
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.quarkus.arc.Arc;
import io.quarkus.arc.InstanceHandle;
import io.quarkus.arc.runtime.BeanContainer;
import io.quarkus.bootstrap.runner.Timing;
import io.quarkus.credentials.CredentialsProvider;
Expand All @@ -69,6 +70,7 @@
import io.quarkus.runtime.util.ClassPathUtils;
import io.quarkus.vertx.core.runtime.VertxCoreRecorder;
import io.quarkus.vertx.core.runtime.config.VertxConfiguration;
import io.quarkus.vertx.http.HttpServerOptionsCustomizer;
import io.quarkus.vertx.http.runtime.HttpConfiguration.InsecureRequests;
import io.quarkus.vertx.http.runtime.devmode.RemoteSyncHandler;
import io.quarkus.vertx.http.runtime.devmode.VertxHttpHotReplacementSetup;
Expand Down Expand Up @@ -125,13 +127,19 @@ public class VertxHttpRecorder {

public static final String MAX_REQUEST_SIZE_KEY = "io.quarkus.max-request-size";

/** Order mark for route with priority over the default route (add an offset from this mark) **/
/**
* 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) **/
/**
* 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) **/
/**
* 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());
Expand Down Expand Up @@ -629,6 +637,7 @@ private void warnIfProxyAddressForwardingAllowedWithMultipleHeaders(HttpConfigur
private static void doServerStart(Vertx vertx, HttpBuildTimeConfig httpBuildTimeConfig,
HttpConfiguration httpConfiguration, LaunchMode launchMode,
Supplier<Integer> eventLoops, List<String> websocketSubProtocols, boolean auxiliaryApplication) throws IOException {

// Http server configuration
HttpServerOptions httpServerOptions = createHttpServerOptions(httpBuildTimeConfig, httpConfiguration, launchMode,
websocketSubProtocols);
Expand All @@ -637,6 +646,24 @@ private static void doServerStart(Vertx vertx, HttpBuildTimeConfig httpBuildTime
HttpServerOptions sslConfig = createSslOptions(httpBuildTimeConfig, httpConfiguration, launchMode,
websocketSubProtocols);

// Customize
if (Arc.container() != null) {
List<InstanceHandle<HttpServerOptionsCustomizer>> instances = Arc.container()
.listAll(HttpServerOptionsCustomizer.class);
for (InstanceHandle<HttpServerOptionsCustomizer> instance : instances) {
HttpServerOptionsCustomizer customizer = instance.get();
if (httpServerOptions != null) {
customizer.customizeHttpServer(httpServerOptions);
}
if (sslConfig != null) {
customizer.customizeHttpsServer(sslConfig);
}
if (domainSocketOptions != null) {
customizer.customizeDomainSocketServer(domainSocketOptions);
}
}
}

if (httpConfiguration.insecureRequests != HttpConfiguration.InsecureRequests.ENABLED && sslConfig == null) {
throw new IllegalStateException("Cannot set quarkus.http.redirect-insecure-requests without enabling SSL.");
}
Expand Down

0 comments on commit b9c3ab4

Please sign in to comment.