From 73d39594b469d31240bcc2dc1fca2121f5bcdf9e Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Wed, 22 Jul 2020 18:03:23 +0200 Subject: [PATCH 1/2] Handle static resources in vertx-http - the logic was moved from RESTEasy standalone - thanks to that static resources are served even for vertx-web --- .../ResteasyStandaloneBuildStep.java | 118 +++------------- .../ResteasyStandaloneRecorder.java | 82 +---------- .../io.quarkus.dev.spi.HotReplacementSetup | 1 - .../deployment/StaticResourcesProcessor.java | 127 ++++++++++++++++++ .../http/deployment/VertxHttpProcessor.java | 3 +- .../vertx/http/runtime/BasicRoute.java | 21 ++- .../http/runtime/StaticResourcesRecorder.java | 91 +++++++++++++ .../vertx/http/runtime/VertxHttpRecorder.java | 5 +- .../StaticResourcesHotReplacementSetup.java} | 14 +- .../io.quarkus.dev.spi.HotReplacementSetup | 1 + 10 files changed, 272 insertions(+), 191 deletions(-) delete mode 100644 extensions/resteasy/runtime/src/main/resources/META-INF/services/io.quarkus.dev.spi.HotReplacementSetup create mode 100644 extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/StaticResourcesProcessor.java create mode 100644 extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/StaticResourcesRecorder.java rename extensions/{resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/devmode/ResteasyHotReplacementSetup.java => vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/StaticResourcesHotReplacementSetup.java} (56%) diff --git a/extensions/resteasy/deployment/src/main/java/io/quarkus/resteasy/deployment/ResteasyStandaloneBuildStep.java b/extensions/resteasy/deployment/src/main/java/io/quarkus/resteasy/deployment/ResteasyStandaloneBuildStep.java index 90fe316bcd0c6..e0fc5649c5d52 100644 --- a/extensions/resteasy/deployment/src/main/java/io/quarkus/resteasy/deployment/ResteasyStandaloneBuildStep.java +++ b/extensions/resteasy/deployment/src/main/java/io/quarkus/resteasy/deployment/ResteasyStandaloneBuildStep.java @@ -3,21 +3,10 @@ import static io.quarkus.deployment.annotations.ExecutionTime.RUNTIME_INIT; import static io.quarkus.deployment.annotations.ExecutionTime.STATIC_INIT; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.HashSet; import java.util.Optional; -import java.util.Set; -import java.util.function.Consumer; import io.quarkus.arc.deployment.BeanContainerBuildItem; import io.quarkus.builder.item.SimpleBuildItem; -import io.quarkus.deployment.ApplicationArchive; import io.quarkus.deployment.Capabilities; import io.quarkus.deployment.Capability; import io.quarkus.deployment.Feature; @@ -31,32 +20,25 @@ import io.quarkus.resteasy.common.deployment.ResteasyInjectionReadyBuildItem; import io.quarkus.resteasy.runtime.standalone.ResteasyStandaloneRecorder; import io.quarkus.resteasy.server.common.deployment.ResteasyDeploymentBuildItem; -import io.quarkus.runtime.util.ClassPathUtils; import io.quarkus.vertx.core.deployment.CoreVertxBuildItem; import io.quarkus.vertx.http.deployment.DefaultRouteBuildItem; import io.quarkus.vertx.http.deployment.RequireVirtualHttpBuildItem; import io.quarkus.vertx.http.deployment.RouteBuildItem; +import io.quarkus.vertx.http.runtime.BasicRoute; import io.quarkus.vertx.http.runtime.HttpBuildTimeConfig; import io.quarkus.vertx.http.runtime.HttpConfiguration; +import io.quarkus.vertx.http.runtime.VertxHttpRecorder; import io.vertx.core.Handler; -import io.vertx.ext.web.Route; import io.vertx.ext.web.RoutingContext; public class ResteasyStandaloneBuildStep { - protected static final String META_INF_RESOURCES_SLASH = "META-INF/resources/"; - protected static final String META_INF_RESOURCES = "META-INF/resources"; - public static final class ResteasyStandaloneBuildItem extends SimpleBuildItem { final String deploymentRootPath; public ResteasyStandaloneBuildItem(String deploymentRootPath) { - if (deploymentRootPath != null) { - this.deploymentRootPath = deploymentRootPath.startsWith("/") ? deploymentRootPath : "/" + deploymentRootPath; - } else { - this.deploymentRootPath = null; - } + this.deploymentRootPath = deploymentRootPath.startsWith("/") ? deploymentRootPath : "/" + deploymentRootPath; } } @@ -74,7 +56,6 @@ public void staticInit(ResteasyStandaloneRecorder recorder, return; } - Set knownPaths = getClasspathResources(applicationArchivesBuildItem); String deploymentRootPath = null; // The context path + the resources path String rootPath = httpConfig.rootPath; @@ -93,64 +74,11 @@ public void staticInit(ResteasyStandaloneRecorder recorder, } rootPath += deploymentRootPath; } - recorder.staticInit(deployment.getDeployment(), rootPath, knownPaths); - - } else if (!knownPaths.isEmpty()) { - recorder.staticInit(null, rootPath, knownPaths); - } - - if (deployment != null || !knownPaths.isEmpty()) { + recorder.staticInit(deployment.getDeployment(), rootPath); standalone.produce(new ResteasyStandaloneBuildItem(deploymentRootPath)); } } - /** - * Find all static file resources that are available from classpath. - * - * @param applicationArchivesBuildItem - * @return - * @throws Exception - */ - private Set getClasspathResources(ApplicationArchivesBuildItem applicationArchivesBuildItem) throws Exception { - Set knownPaths = new HashSet<>(); - for (ApplicationArchive i : applicationArchivesBuildItem.getAllApplicationArchives()) { - Path resource = i.getChildPath(META_INF_RESOURCES); - if (resource != null && Files.exists(resource)) { - collectKnownPaths(resource, knownPaths); - } - } - - ClassPathUtils.consumeAsPaths(META_INF_RESOURCES, resource -> { - collectKnownPaths(resource, knownPaths); - }); - - return knownPaths; - } - - private void collectKnownPaths(Path resource, Set knownPaths) { - try { - Files.walkFileTree(resource, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path p, BasicFileAttributes attrs) - throws IOException { - String file = resource.relativize(p).toString(); - if (file.equals("index.html") || file.equals("index.htm")) { - knownPaths.add("/"); - } - if (!file.startsWith("/")) { - file = "/" + file; - } - // Windows has a backslash - file = file.replace('\\', '/'); - knownPaths.add(file); - return FileVisitResult.CONTINUE; - } - }); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - @BuildStep @Record(RUNTIME_INIT) public void boot(ShutdownContextBuildItem shutdown, @@ -170,31 +98,23 @@ public void boot(ShutdownContextBuildItem shutdown, } feature.produce(new FeatureBuildItem(Feature.RESTEASY)); - boolean isDefaultOrNullDeploymentPath = standalone.deploymentRootPath == null - || standalone.deploymentRootPath.equals("/"); - if (!isDefaultOrNullDeploymentPath) { - // We need to register a special handler for non-default deployment path (specified as application path or resteasyConfig.path) - Handler handler = recorder.vertxRequestHandler(vertx.getVertx(), beanContainer.getValue(), - executorBuildItem.getExecutorProxy(), httpConfiguration); - // Exact match for resources matched to the root path - routes.produce(new RouteBuildItem(standalone.deploymentRootPath, handler, false)); - String matchPath = standalone.deploymentRootPath; - if (matchPath.endsWith("/")) { - matchPath += "*"; - } else { - matchPath += "/*"; - } - // Match paths that begin with the deployment path - routes.produce(new RouteBuildItem(matchPath, handler, false)); + // Handler used for both the default and non-default deployment path (specified as application path or resteasyConfig.path) + // Routes use the order VertxHttpRecorder.DEFAULT_ROUTE_ORDER + 1 to ensure the default route is called before the resteasy one + Handler handler = recorder.vertxRequestHandler(vertx.getVertx(), beanContainer.getValue(), + executorBuildItem.getExecutorProxy(), httpConfiguration); + // Exact match for resources matched to the root path + routes.produce(new RouteBuildItem( + new BasicRoute(standalone.deploymentRootPath, VertxHttpRecorder.DEFAULT_ROUTE_ORDER + 1), handler)); + String matchPath = standalone.deploymentRootPath; + if (matchPath.endsWith("/")) { + matchPath += "*"; + } else { + matchPath += "/*"; } + // Match paths that begin with the deployment path + routes.produce(new RouteBuildItem(new BasicRoute(matchPath, VertxHttpRecorder.DEFAULT_ROUTE_ORDER + 1), handler)); - boolean isVirtual = requireVirtual.isPresent(); - Consumer ut = recorder.start(vertx.getVertx(), - shutdown, - beanContainer.getValue(), - isVirtual, isDefaultOrNullDeploymentPath, executorBuildItem.getExecutorProxy(), httpConfiguration); - - defaultRoutes.produce(new DefaultRouteBuildItem(ut)); + recorder.start(shutdown, requireVirtual.isPresent()); } } diff --git a/extensions/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/standalone/ResteasyStandaloneRecorder.java b/extensions/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/standalone/ResteasyStandaloneRecorder.java index 00c3e8cecf0ab..c40e32aec28b7 100644 --- a/extensions/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/standalone/ResteasyStandaloneRecorder.java +++ b/extensions/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/standalone/ResteasyStandaloneRecorder.java @@ -1,11 +1,6 @@ package io.quarkus.resteasy.runtime.standalone; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; import java.util.concurrent.Executor; -import java.util.function.Consumer; import java.util.function.Supplier; import org.jboss.resteasy.spi.ResteasyDeployment; @@ -16,12 +11,9 @@ import io.quarkus.runtime.ShutdownContext; import io.quarkus.runtime.annotations.Recorder; import io.quarkus.vertx.http.runtime.HttpConfiguration; -import io.quarkus.vertx.http.runtime.ThreadLocalHandler; import io.vertx.core.Handler; import io.vertx.core.Vertx; -import io.vertx.ext.web.Route; import io.vertx.ext.web.RoutingContext; -import io.vertx.ext.web.handler.StaticHandler; /** * Provides the runtime methods to bootstrap Resteasy in standalone mode. @@ -70,30 +62,18 @@ public int getBufferSize() { } }; - private static volatile List hotDeploymentResourcePaths; - - public static void setHotDeploymentResources(List resources) { - hotDeploymentResourcePaths = resources; - } - private static ResteasyDeployment deployment; - private static Set knownPaths; private static String contextPath; - public void staticInit(ResteasyDeployment dep, String path, Set known) { + public void staticInit(ResteasyDeployment dep, String path) { if (dep != null) { deployment = dep; deployment.start(); } - knownPaths = known; contextPath = path; } - public Consumer start(Supplier vertx, - ShutdownContext shutdown, - BeanContainer beanContainer, - boolean isVirtual, boolean isDefaultResourcesPath, - Executor executor, HttpConfiguration httpConfiguration) { + public void start(ShutdownContext shutdown, boolean isVirtual) { shutdown.addShutdownTask(new Runnable() { @Override @@ -104,64 +84,6 @@ public void run() { } }); useDirect = !isVirtual; - List> handlers = new ArrayList<>(); - - if (hotDeploymentResourcePaths != null && !hotDeploymentResourcePaths.isEmpty()) { - for (Path resourcePath : hotDeploymentResourcePaths) { - String root = resourcePath.toAbsolutePath().toString(); - ThreadLocalHandler staticHandler = new ThreadLocalHandler(new Supplier>() { - @Override - public Handler get() { - StaticHandler staticHandler = StaticHandler.create(); - staticHandler.setCachingEnabled(false); - staticHandler.setAllowRootFileSystemAccess(true); - staticHandler.setWebRoot(root); - staticHandler.setDefaultContentEncoding("UTF-8"); - return staticHandler; - } - }); - handlers.add(event -> { - try { - staticHandler.handle(event); - } catch (Exception e) { - // on Windows, the drive in file path screws up cache lookup - // so just punt to next handler - event.next(); - } - }); - } - } - if (!knownPaths.isEmpty()) { - ThreadLocalHandler staticHandler = new ThreadLocalHandler(new Supplier>() { - @Override - public Handler get() { - return StaticHandler.create(META_INF_RESOURCES) - .setDefaultContentEncoding("UTF-8"); - } - }); - handlers.add(ctx -> { - String rel = ctx.mountPoint() == null ? ctx.normalisedPath() - : ctx.normalisedPath().substring(ctx.mountPoint().length()); - if (knownPaths.contains(rel)) { - staticHandler.handle(ctx); - } else { - ctx.next(); - } - }); - } - - if (deployment != null && isDefaultResourcesPath) { - handlers.add(vertxRequestHandler(vertx, beanContainer, executor, httpConfiguration)); - } - return new Consumer() { - - @Override - public void accept(Route route) { - for (Handler i : handlers) { - route.handler(i); - } - } - }; } public Handler vertxRequestHandler(Supplier vertx, diff --git a/extensions/resteasy/runtime/src/main/resources/META-INF/services/io.quarkus.dev.spi.HotReplacementSetup b/extensions/resteasy/runtime/src/main/resources/META-INF/services/io.quarkus.dev.spi.HotReplacementSetup deleted file mode 100644 index 5100a407f5e12..0000000000000 --- a/extensions/resteasy/runtime/src/main/resources/META-INF/services/io.quarkus.dev.spi.HotReplacementSetup +++ /dev/null @@ -1 +0,0 @@ -io.quarkus.resteasy.runtime.devmode.ResteasyHotReplacementSetup \ No newline at end of file diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/StaticResourcesProcessor.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/StaticResourcesProcessor.java new file mode 100644 index 0000000000000..609e0b659698d --- /dev/null +++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/StaticResourcesProcessor.java @@ -0,0 +1,127 @@ +package io.quarkus.vertx.http.deployment; + +import static io.quarkus.deployment.annotations.ExecutionTime.RUNTIME_INIT; +import static io.quarkus.deployment.annotations.ExecutionTime.STATIC_INIT; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; + +import io.quarkus.arc.deployment.BeanContainerBuildItem; +import io.quarkus.builder.item.SimpleBuildItem; +import io.quarkus.deployment.ApplicationArchive; +import io.quarkus.deployment.Capabilities; +import io.quarkus.deployment.Capability; +import io.quarkus.deployment.annotations.BuildProducer; +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.annotations.Record; +import io.quarkus.deployment.builditem.ApplicationArchivesBuildItem; +import io.quarkus.runtime.util.ClassPathUtils; +import io.quarkus.vertx.core.deployment.CoreVertxBuildItem; +import io.quarkus.vertx.http.runtime.StaticResourcesRecorder; + +/** + * Handles all static file resources found in {@code META-INF/resources} unless the servlet container is present. + */ +public class StaticResourcesProcessor { + + public static final class StaticResourcesBuildItem extends SimpleBuildItem { + + private final Set paths; + + public StaticResourcesBuildItem(Set paths) { + this.paths = paths; + } + + public Set getPaths() { + return paths; + } + + } + + @BuildStep + void collectStaticResources(Capabilities capabilities, ApplicationArchivesBuildItem applicationArchivesBuildItem, + BuildProducer staticResources) throws Exception { + if (capabilities.isPresent(Capability.SERVLET)) { + // Servlet container handles static resources + return; + } + Set paths = getClasspathResources(applicationArchivesBuildItem); + if (!paths.isEmpty()) { + staticResources.produce(new StaticResourcesBuildItem(paths)); + } + } + + @BuildStep + @Record(STATIC_INIT) + public void staticInit(Optional staticResources, + StaticResourcesRecorder recorder) throws Exception { + if (staticResources.isPresent()) { + recorder.staticInit(staticResources.get().getPaths()); + } + } + + @BuildStep + @Record(RUNTIME_INIT) + public void runtimeInit(Optional staticResources, StaticResourcesRecorder recorder, + CoreVertxBuildItem vertx, BeanContainerBuildItem beanContainer, BuildProducer defaultRoutes) + throws Exception { + if (staticResources.isPresent()) { + defaultRoutes.produce(new DefaultRouteBuildItem(recorder.start())); + } + } + + /** + * Find all static file resources that are available from classpath. + * + * @param applicationArchivesBuildItem + * @return the set of static resources + * @throws Exception + */ + private Set getClasspathResources(ApplicationArchivesBuildItem applicationArchivesBuildItem) throws Exception { + Set knownPaths = new HashSet<>(); + for (ApplicationArchive i : applicationArchivesBuildItem.getAllApplicationArchives()) { + Path resource = i.getChildPath(StaticResourcesRecorder.META_INF_RESOURCES); + if (resource != null && Files.exists(resource)) { + collectKnownPaths(resource, knownPaths); + } + } + + ClassPathUtils.consumeAsPaths(StaticResourcesRecorder.META_INF_RESOURCES, resource -> { + collectKnownPaths(resource, knownPaths); + }); + + return knownPaths; + } + + private void collectKnownPaths(Path resource, Set knownPaths) { + try { + Files.walkFileTree(resource, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path p, BasicFileAttributes attrs) + throws IOException { + String file = resource.relativize(p).toString(); + if (file.equals("index.html") || file.equals("index.htm")) { + knownPaths.add("/"); + } + if (!file.startsWith("/")) { + file = "/" + file; + } + // Windows has a backslash + file = file.replace('\\', '/'); + knownPaths.add(file); + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } +} diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/VertxHttpProcessor.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/VertxHttpProcessor.java index 81fdc0c70ee3f..fd08e49209d6f 100644 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/VertxHttpProcessor.java +++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/VertxHttpProcessor.java @@ -136,7 +136,7 @@ ServiceStartBuildItem finalizeRouter( CoreVertxBuildItem core, // Injected to be sure that Vert.x has been produced before calling this method. ExecutorBuildItem executorBuildItem) throws BuildException, IOException { - HttpRemoteDevClientProvider.liveReloadConfig = lrc; + Optional defaultRoute; if (defaultRoutes == null || defaultRoutes.isEmpty()) { defaultRoute = Optional.empty(); @@ -149,6 +149,7 @@ ServiceStartBuildItem finalizeRouter( } } + HttpRemoteDevClientProvider.liveReloadConfig = lrc; GracefulShutdownFilter gracefulShutdownFilter = recorder.createGracefulShutdownHandler(); shutdownListenerBuildItemBuildProducer.produce(new ShutdownListenerBuildItem(gracefulShutdownFilter)); diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/BasicRoute.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/BasicRoute.java index 5af7355c2006b..181e5cbd8d761 100644 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/BasicRoute.java +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/BasicRoute.java @@ -9,8 +9,15 @@ public class BasicRoute implements Function { private String path; + private Integer order; + public BasicRoute(String path) { + this(path, null); + } + + public BasicRoute(String path, Integer order) { this.path = path; + this.order = order; } public BasicRoute() { @@ -24,8 +31,20 @@ public void setPath(String path) { this.path = path; } + public Integer getOrder() { + return order; + } + + public void setOrder(Integer order) { + this.order = order; + } + @Override public Route apply(Router router) { - return router.route(path); + Route route = router.route(path); + if (order != null) { + route.order(order); + } + return route; } } diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/StaticResourcesRecorder.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/StaticResourcesRecorder.java new file mode 100644 index 0000000000000..36b435df3f2b4 --- /dev/null +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/StaticResourcesRecorder.java @@ -0,0 +1,91 @@ +package io.quarkus.vertx.http.runtime; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.function.Consumer; +import java.util.function.Supplier; + +import io.quarkus.runtime.annotations.Recorder; +import io.vertx.core.Handler; +import io.vertx.ext.web.Route; +import io.vertx.ext.web.RoutingContext; +import io.vertx.ext.web.handler.StaticHandler; + +@Recorder +public class StaticResourcesRecorder { + + public static final String META_INF_RESOURCES = "META-INF/resources"; + + private static volatile Set knownPaths; + private static volatile List hotDeploymentResourcePaths; + + public static void setHotDeploymentResources(List resources) { + hotDeploymentResourcePaths = resources; + } + + public void staticInit(Set knownPaths) { + StaticResourcesRecorder.knownPaths = knownPaths; + } + + public Consumer start() { + + List> handlers = new ArrayList<>(); + + if (hotDeploymentResourcePaths != null && !hotDeploymentResourcePaths.isEmpty()) { + for (Path resourcePath : hotDeploymentResourcePaths) { + String root = resourcePath.toAbsolutePath().toString(); + ThreadLocalHandler staticHandler = new ThreadLocalHandler(new Supplier>() { + @Override + public Handler get() { + StaticHandler staticHandler = StaticHandler.create(); + staticHandler.setCachingEnabled(false); + staticHandler.setAllowRootFileSystemAccess(true); + staticHandler.setWebRoot(root); + staticHandler.setDefaultContentEncoding("UTF-8"); + return staticHandler; + } + }); + handlers.add(event -> { + try { + staticHandler.handle(event); + } catch (Exception e) { + // on Windows, the drive in file path screws up cache lookup + // so just punt to next handler + event.next(); + } + }); + } + } + if (!knownPaths.isEmpty()) { + ThreadLocalHandler staticHandler = new ThreadLocalHandler(new Supplier>() { + @Override + public Handler get() { + return StaticHandler.create(META_INF_RESOURCES) + .setDefaultContentEncoding("UTF-8"); + } + }); + handlers.add(ctx -> { + String rel = ctx.mountPoint() == null ? ctx.normalisedPath() + : ctx.normalisedPath().substring(ctx.mountPoint().length()); + if (knownPaths.contains(rel)) { + staticHandler.handle(ctx); + } else { + ctx.next(); + } + }); + } + + return new Consumer() { + + @Override + public void accept(Route route) { + for (Handler i : handlers) { + route.handler(i); + } + } + }; + } + +} diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/VertxHttpRecorder.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/VertxHttpRecorder.java index 28e79a142dd0a..a240b7ec37f26 100644 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/VertxHttpRecorder.java +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/VertxHttpRecorder.java @@ -105,6 +105,9 @@ public class VertxHttpRecorder { public static final String MAX_REQUEST_SIZE_KEY = "io.quarkus.max-request-size"; + // We don not use Integer.MAX on purpose to allow advanced users to register a route AFTER the default route + public static final int DEFAULT_ROUTE_ORDER = 10_000; + private static final Logger LOGGER = Logger.getLogger(VertxHttpRecorder.class.getName()); private static volatile Handler hotReplacementHandler; @@ -252,7 +255,7 @@ public void finalizeRouter(BeanContainer container, Consumer defaultRoute } if (defaultRouteHandler != null) { - defaultRouteHandler.accept(router.route().order(10_000)); + defaultRouteHandler.accept(router.route().order(DEFAULT_ROUTE_ORDER)); } container.instance(RouterProducer.class).initialize(router); diff --git a/extensions/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/devmode/ResteasyHotReplacementSetup.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/StaticResourcesHotReplacementSetup.java similarity index 56% rename from extensions/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/devmode/ResteasyHotReplacementSetup.java rename to extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/StaticResourcesHotReplacementSetup.java index 03d6fa0fac145..dd531a7a0520b 100644 --- a/extensions/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/devmode/ResteasyHotReplacementSetup.java +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/StaticResourcesHotReplacementSetup.java @@ -1,4 +1,4 @@ -package io.quarkus.resteasy.runtime.devmode; +package io.quarkus.vertx.http.runtime.devmode; import java.nio.file.Files; import java.nio.file.Path; @@ -7,22 +7,20 @@ import io.quarkus.dev.spi.HotReplacementContext; import io.quarkus.dev.spi.HotReplacementSetup; -import io.quarkus.resteasy.runtime.standalone.ResteasyStandaloneRecorder; +import io.quarkus.vertx.http.runtime.StaticResourcesRecorder; -public class ResteasyHotReplacementSetup implements HotReplacementSetup { - - public static final String META_INF_RESOURCES = "META-INF/resources"; +public class StaticResourcesHotReplacementSetup implements HotReplacementSetup { @Override public void setupHotDeployment(HotReplacementContext context) { List resources = new ArrayList<>(); for (Path resourceDir : context.getResourcesDir()) { - Path resource = resourceDir.resolve(META_INF_RESOURCES); + Path resource = resourceDir.resolve(StaticResourcesRecorder.META_INF_RESOURCES); if (Files.exists(resource)) { resources.add(resource); } } - ResteasyStandaloneRecorder.setHotDeploymentResources(resources); + StaticResourcesRecorder.setHotDeploymentResources(resources); } @Override @@ -31,6 +29,6 @@ public void handleFailedInitialStart() { @Override public void close() { - ResteasyStandaloneRecorder.setHotDeploymentResources(null); + StaticResourcesRecorder.setHotDeploymentResources(null); } } diff --git a/extensions/vertx-http/runtime/src/main/resources/META-INF/services/io.quarkus.dev.spi.HotReplacementSetup b/extensions/vertx-http/runtime/src/main/resources/META-INF/services/io.quarkus.dev.spi.HotReplacementSetup index a145c9cb76597..6d2e0a33a76df 100644 --- a/extensions/vertx-http/runtime/src/main/resources/META-INF/services/io.quarkus.dev.spi.HotReplacementSetup +++ b/extensions/vertx-http/runtime/src/main/resources/META-INF/services/io.quarkus.dev.spi.HotReplacementSetup @@ -1 +1,2 @@ io.quarkus.vertx.http.runtime.devmode.VertxHttpHotReplacementSetup +io.quarkus.vertx.http.runtime.devmode.StaticResourcesHotReplacementSetup \ No newline at end of file From 9d408d892d1ecc95fad98952c7012dd4ee12cbb5 Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Thu, 23 Jul 2020 16:00:10 +0200 Subject: [PATCH 2/2] Get rid of ThreadLocalHandler - used to workaround https://github.com/vert-x3/vertx-web/issues/1429 --- .../runtime/SmallRyeGraphQLRecorder.java | 16 +++--------- .../runtime/SmallRyeHealthRecorder.java | 16 +++--------- .../swaggerui/runtime/SwaggerUiRecorder.java | 16 +++--------- .../http/runtime/StaticResourcesRecorder.java | 25 +++++-------------- .../http/runtime/ThreadLocalHandler.java | 25 ------------------- .../vertx/http/runtime/VertxHttpRecorder.java | 2 +- 6 files changed, 19 insertions(+), 81 deletions(-) delete mode 100644 extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/ThreadLocalHandler.java diff --git a/extensions/smallrye-graphql/runtime/src/main/java/io/quarkus/smallrye/graphql/runtime/SmallRyeGraphQLRecorder.java b/extensions/smallrye-graphql/runtime/src/main/java/io/quarkus/smallrye/graphql/runtime/SmallRyeGraphQLRecorder.java index 111bb4fae199c..a993ba90ad40f 100644 --- a/extensions/smallrye-graphql/runtime/src/main/java/io/quarkus/smallrye/graphql/runtime/SmallRyeGraphQLRecorder.java +++ b/extensions/smallrye-graphql/runtime/src/main/java/io/quarkus/smallrye/graphql/runtime/SmallRyeGraphQLRecorder.java @@ -1,7 +1,5 @@ package io.quarkus.smallrye.graphql.runtime; -import java.util.function.Supplier; - import javax.enterprise.inject.Instance; import javax.enterprise.inject.spi.CDI; @@ -10,7 +8,6 @@ import io.quarkus.runtime.annotations.Recorder; import io.quarkus.security.identity.CurrentIdentityAssociation; import io.quarkus.smallrye.graphql.runtime.spi.QuarkusClassloadingService; -import io.quarkus.vertx.http.runtime.ThreadLocalHandler; import io.smallrye.graphql.cdi.producer.GraphQLProducer; import io.smallrye.graphql.schema.model.Schema; import io.vertx.core.Handler; @@ -45,14 +42,9 @@ public Handler schemaHandler() { public Handler uiHandler(String graphqlUiFinalDestination, String graphqlUiPath) { - Handler handler = new ThreadLocalHandler(new Supplier>() { - @Override - public Handler get() { - return StaticHandler.create().setAllowRootFileSystemAccess(true) - .setWebRoot(graphqlUiFinalDestination) - .setDefaultContentEncoding("UTF-8"); - } - }); + StaticHandler staticHandler = StaticHandler.create().setAllowRootFileSystemAccess(true) + .setWebRoot(graphqlUiFinalDestination) + .setDefaultContentEncoding("UTF-8"); return new Handler() { @Override @@ -68,7 +60,7 @@ public void handle(RoutingContext event) { return; } - handler.handle(event); + staticHandler.handle(event); } }; } diff --git a/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeHealthRecorder.java b/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeHealthRecorder.java index f018d407488c8..ef24518be6bf0 100644 --- a/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeHealthRecorder.java +++ b/extensions/smallrye-health/runtime/src/main/java/io/quarkus/smallrye/health/runtime/SmallRyeHealthRecorder.java @@ -1,12 +1,9 @@ package io.quarkus.smallrye.health.runtime; -import java.util.function.Supplier; - import org.eclipse.microprofile.health.HealthCheckResponse; import org.eclipse.microprofile.health.spi.HealthCheckResponseProvider; import io.quarkus.runtime.annotations.Recorder; -import io.quarkus.vertx.http.runtime.ThreadLocalHandler; import io.vertx.core.Handler; import io.vertx.core.http.HttpHeaders; import io.vertx.ext.web.RoutingContext; @@ -26,14 +23,9 @@ public void registerHealthCheckResponseProvider(Class uiHandler(String healthUiFinalDestination, String healthUiPath) { - Handler handler = new ThreadLocalHandler(new Supplier>() { - @Override - public Handler get() { - return StaticHandler.create().setAllowRootFileSystemAccess(true) - .setWebRoot(healthUiFinalDestination) - .setDefaultContentEncoding("UTF-8"); - } - }); + StaticHandler staticHandler = StaticHandler.create().setAllowRootFileSystemAccess(true) + .setWebRoot(healthUiFinalDestination) + .setDefaultContentEncoding("UTF-8"); return new Handler() { @Override @@ -49,7 +41,7 @@ public void handle(RoutingContext event) { return; } - handler.handle(event); + staticHandler.handle(event); } }; } diff --git a/extensions/swagger-ui/runtime/src/main/java/io/quarkus/swaggerui/runtime/SwaggerUiRecorder.java b/extensions/swagger-ui/runtime/src/main/java/io/quarkus/swaggerui/runtime/SwaggerUiRecorder.java index c59d3ee98cbed..745e8122f276b 100644 --- a/extensions/swagger-ui/runtime/src/main/java/io/quarkus/swaggerui/runtime/SwaggerUiRecorder.java +++ b/extensions/swagger-ui/runtime/src/main/java/io/quarkus/swaggerui/runtime/SwaggerUiRecorder.java @@ -1,9 +1,6 @@ package io.quarkus.swaggerui.runtime; -import java.util.function.Supplier; - import io.quarkus.runtime.annotations.Recorder; -import io.quarkus.vertx.http.runtime.ThreadLocalHandler; import io.vertx.core.Handler; import io.vertx.core.http.HttpHeaders; import io.vertx.ext.web.RoutingContext; @@ -13,14 +10,9 @@ public class SwaggerUiRecorder { public Handler handler(String swaggerUiFinalDestination, String swaggerUiPath) { - Handler handler = new ThreadLocalHandler(new Supplier>() { - @Override - public Handler get() { - return StaticHandler.create().setAllowRootFileSystemAccess(true) - .setWebRoot(swaggerUiFinalDestination) - .setDefaultContentEncoding("UTF-8"); - } - }); + StaticHandler staticHandler = StaticHandler.create().setAllowRootFileSystemAccess(true) + .setWebRoot(swaggerUiFinalDestination) + .setDefaultContentEncoding("UTF-8"); return new Handler() { @Override @@ -36,7 +28,7 @@ public void handle(RoutingContext event) { return; } - handler.handle(event); + staticHandler.handle(event); } }; } diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/StaticResourcesRecorder.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/StaticResourcesRecorder.java index 36b435df3f2b4..9fb213e27e2ad 100644 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/StaticResourcesRecorder.java +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/StaticResourcesRecorder.java @@ -5,7 +5,6 @@ import java.util.List; import java.util.Set; import java.util.function.Consumer; -import java.util.function.Supplier; import io.quarkus.runtime.annotations.Recorder; import io.vertx.core.Handler; @@ -36,17 +35,11 @@ public Consumer start() { if (hotDeploymentResourcePaths != null && !hotDeploymentResourcePaths.isEmpty()) { for (Path resourcePath : hotDeploymentResourcePaths) { String root = resourcePath.toAbsolutePath().toString(); - ThreadLocalHandler staticHandler = new ThreadLocalHandler(new Supplier>() { - @Override - public Handler get() { - StaticHandler staticHandler = StaticHandler.create(); - staticHandler.setCachingEnabled(false); - staticHandler.setAllowRootFileSystemAccess(true); - staticHandler.setWebRoot(root); - staticHandler.setDefaultContentEncoding("UTF-8"); - return staticHandler; - } - }); + StaticHandler staticHandler = StaticHandler.create(); + staticHandler.setCachingEnabled(false); + staticHandler.setAllowRootFileSystemAccess(true); + staticHandler.setWebRoot(root); + staticHandler.setDefaultContentEncoding("UTF-8"); handlers.add(event -> { try { staticHandler.handle(event); @@ -59,13 +52,7 @@ public Handler get() { } } if (!knownPaths.isEmpty()) { - ThreadLocalHandler staticHandler = new ThreadLocalHandler(new Supplier>() { - @Override - public Handler get() { - return StaticHandler.create(META_INF_RESOURCES) - .setDefaultContentEncoding("UTF-8"); - } - }); + StaticHandler staticHandler = StaticHandler.create(META_INF_RESOURCES).setDefaultContentEncoding("UTF-8"); handlers.add(ctx -> { String rel = ctx.mountPoint() == null ? ctx.normalisedPath() : ctx.normalisedPath().substring(ctx.mountPoint().length()); diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/ThreadLocalHandler.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/ThreadLocalHandler.java deleted file mode 100644 index e3be0dede558c..0000000000000 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/ThreadLocalHandler.java +++ /dev/null @@ -1,25 +0,0 @@ -package io.quarkus.vertx.http.runtime; - -import java.util.function.Supplier; - -import io.vertx.core.Handler; -import io.vertx.ext.web.RoutingContext; - -public class ThreadLocalHandler implements Handler { - - private final ThreadLocal> threadLocal; - - public ThreadLocalHandler(Supplier> supplier) { - threadLocal = new ThreadLocal>() { - @Override - protected Handler initialValue() { - return supplier.get(); - } - }; - } - - @Override - public void handle(RoutingContext event) { - threadLocal.get().handle(event); - } -} diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/VertxHttpRecorder.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/VertxHttpRecorder.java index a240b7ec37f26..5a39a7b39d5e4 100644 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/VertxHttpRecorder.java +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/VertxHttpRecorder.java @@ -105,7 +105,7 @@ public class VertxHttpRecorder { public static final String MAX_REQUEST_SIZE_KEY = "io.quarkus.max-request-size"; - // We don not use Integer.MAX on purpose to allow advanced users to register a route AFTER the default route + // We do not use Integer.MAX on purpose to allow advanced users to register a route AFTER the default route public static final int DEFAULT_ROUTE_ORDER = 10_000; private static final Logger LOGGER = Logger.getLogger(VertxHttpRecorder.class.getName());