diff --git a/docs/src/main/asciidoc/vertx-reference.adoc b/docs/src/main/asciidoc/vertx-reference.adoc index fdbce22683c10..52d46e6f2f665 100644 --- a/docs/src/main/asciidoc/vertx-reference.adoc +++ b/docs/src/main/asciidoc/vertx-reference.adoc @@ -1039,3 +1039,25 @@ java.lang.IllegalStateException: Failed to create cache dir ---- Assuming `/tmp/` is writable this can be fixed by setting the `vertx.cacheDirBase` property to point to a directory in `/tmp/` for instance in OpenShift by creating an environment variable `JAVA_OPTS` with the value `-Dvertx.cacheDirBase=/tmp/vertx`. + +== Customizing the Vert.x configuration + +The configuration of the managed Vert.x instance can be provided using the `application.properties` file, but also using _special beans_. +CDI beans exposing the `io.quarkus.vertx.VertxOptionsCustomizer` interface can be used to customize the Vert.x configuration. +For example, the following customizer change the `tmp` base directory: + +[source, java] +---- +@ApplicationScoped +public class MyCustomizer implements VertxOptionsCustomizer { + + @Override + public void accept(VertxOptions options) { + options.setFileSystemOptions(new FileSystemOptions().setFileCacheDir("target")); + } +} +---- + +The _customizer_ beans received the `VertxOptions` (coming from the application configuration), and can modify them. + + diff --git a/extensions/vertx/deployment/src/main/java/io/quarkus/vertx/core/deployment/VertxCoreProcessor.java b/extensions/vertx/deployment/src/main/java/io/quarkus/vertx/core/deployment/VertxCoreProcessor.java index 14ca4572bcf6e..b5fb5a0334c55 100644 --- a/extensions/vertx/deployment/src/main/java/io/quarkus/vertx/core/deployment/VertxCoreProcessor.java +++ b/extensions/vertx/deployment/src/main/java/io/quarkus/vertx/core/deployment/VertxCoreProcessor.java @@ -28,6 +28,7 @@ import org.objectweb.asm.Type; import io.quarkus.arc.deployment.SyntheticBeanBuildItem; +import io.quarkus.arc.deployment.UnremovableBeanBuildItem; import io.quarkus.bootstrap.classloading.QuarkusClassLoader; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; @@ -50,6 +51,7 @@ import io.quarkus.deployment.logging.LogCleanupFilterBuildItem; import io.quarkus.gizmo.Gizmo; import io.quarkus.netty.deployment.EventLoopSupplierBuildItem; +import io.quarkus.vertx.VertxOptionsCustomizer; import io.quarkus.vertx.core.runtime.VertxCoreRecorder; import io.quarkus.vertx.core.runtime.VertxLocalsHelper; import io.quarkus.vertx.core.runtime.VertxLogDelegateFactory; @@ -247,6 +249,11 @@ void registerVerticleClasses(CombinedIndexBuildItem indexBuildItem, } } + @BuildStep + void doNotRemoveVertxOptionsCustomizers(BuildProducer unremovable) { + unremovable.produce(UnremovableBeanBuildItem.beanTypes(VertxOptionsCustomizer.class)); + } + @BuildStep @Record(ExecutionTime.RUNTIME_INIT) ThreadFactoryBuildItem createVertxThreadFactory(VertxCoreRecorder recorder, LaunchModeBuildItem launchMode) { diff --git a/extensions/vertx/deployment/src/test/java/io/quarkus/vertx/customizers/VertxOptionsCustomizerTest.java b/extensions/vertx/deployment/src/test/java/io/quarkus/vertx/customizers/VertxOptionsCustomizerTest.java new file mode 100644 index 0000000000000..47cc596be71a1 --- /dev/null +++ b/extensions/vertx/deployment/src/test/java/io/quarkus/vertx/customizers/VertxOptionsCustomizerTest.java @@ -0,0 +1,53 @@ +package io.quarkus.vertx.customizers; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; + +import org.assertj.core.api.Assertions; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; +import io.quarkus.vertx.VertxOptionsCustomizer; +import io.vertx.core.VertxOptions; +import io.vertx.core.file.FileSystemOptions; +import io.vertx.mutiny.core.Vertx; + +public class VertxOptionsCustomizerTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .setArchiveProducer(() -> ShrinkWrap + .create(JavaArchive.class).addClasses(MyCustomizer.class)); + + @Inject + Vertx vertx; + + @Inject + MyCustomizer customizer; + + @Test + public void testCustomizer() { + Assertions.assertThat(customizer.wasInvoked()).isTrue(); + String test = vertx.fileSystem().createTempDirectoryAndAwait("test"); + Assertions.assertThat(test).contains("target", "test"); + } + + @ApplicationScoped + public static class MyCustomizer implements VertxOptionsCustomizer { + + volatile boolean invoked; + + @Override + public void accept(VertxOptions options) { + invoked = true; + options.setFileSystemOptions(new FileSystemOptions().setFileCacheDir("target")); + } + + public boolean wasInvoked() { + return invoked; + } + } +} diff --git a/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/VertxOptionsCustomizer.java b/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/VertxOptionsCustomizer.java new file mode 100644 index 0000000000000..0894c2757cb5c --- /dev/null +++ b/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/VertxOptionsCustomizer.java @@ -0,0 +1,15 @@ +package io.quarkus.vertx; + +import java.util.function.Consumer; + +import io.vertx.core.VertxOptions; + +/** + * Allows customizing the {@link VertxOptions} used to create the managed {@link io.vertx.core.Vertx} instance. + *

+ * Beans exposing this interface receive the {@link VertxOptions} computed from the application configuration, and + * extensions customizing the options. + */ +public interface VertxOptionsCustomizer extends Consumer { + +} diff --git a/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/core/runtime/VertxCoreRecorder.java b/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/core/runtime/VertxCoreRecorder.java index 80964a3e6b868..4a4161d600573 100644 --- a/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/core/runtime/VertxCoreRecorder.java +++ b/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/core/runtime/VertxCoreRecorder.java @@ -32,6 +32,8 @@ import io.netty.channel.EventLoopGroup; import io.netty.util.concurrent.FastThreadLocal; +import io.quarkus.arc.Arc; +import io.quarkus.arc.InstanceHandle; import io.quarkus.runtime.IOThreadDetector; import io.quarkus.runtime.LaunchMode; import io.quarkus.runtime.ShutdownContext; @@ -597,6 +599,13 @@ static class VertxOptionsCustomizer { VertxOptionsCustomizer(List> customizers) { this.customizers = customizers; + if (Arc.container() != null) { + List> instances = Arc.container() + .listAll(io.quarkus.vertx.VertxOptionsCustomizer.class); + for (InstanceHandle customizer : instances) { + customizers.add(customizer.get()); + } + } } VertxOptions customize(VertxOptions options) {