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

Allows Vert.x HTTP Options customization #26767

Merged
merged 1 commit into from
Jul 19, 2022
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
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