diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveDevModeProcessor.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveDevModeProcessor.java index b9497e15b9276..139495de31719 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveDevModeProcessor.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveDevModeProcessor.java @@ -29,6 +29,7 @@ import io.quarkus.deployment.builditem.ApplicationArchivesBuildItem; import io.quarkus.deployment.builditem.ConsoleCommandBuildItem; import io.quarkus.deployment.console.QuarkusCommand; +import io.quarkus.devui.deployment.ide.IdeProcessor; import io.quarkus.resteasy.reactive.server.runtime.ExceptionMapperRecorder; import io.quarkus.resteasy.reactive.server.runtime.NotFoundExceptionMapper; import io.quarkus.resteasy.reactive.spi.CustomExceptionMapperBuildItem; @@ -36,7 +37,6 @@ import io.quarkus.vertx.http.deployment.NonApplicationRootPathBuildItem; import io.quarkus.vertx.http.deployment.devmode.NotFoundPageDisplayableEndpointBuildItem; import io.quarkus.vertx.http.deployment.devmode.RouteDescriptionBuildItem; -import io.quarkus.vertx.http.deployment.devmode.console.DevConsoleProcessor; import io.quarkus.vertx.http.runtime.devmode.AdditionalRouteDescription; import io.quarkus.vertx.http.runtime.devmode.RouteDescription; @@ -150,7 +150,7 @@ public OpenCommand(HttpRootPathBuildItem rp, NonApplicationRootPathBuildItem np, @Override public CommandResult doExecute(CommandInvocation commandInvocation) throws CommandException, InterruptedException { - DevConsoleProcessor.openBrowser(rp, np, url.startsWith("/") ? url : "/" + url, host, port); + IdeProcessor.openBrowser(rp, np, url.startsWith("/") ? url : "/" + url, host, port); return CommandResult.SUCCESS; } } diff --git a/extensions/vertx-http/deployment/pom.xml b/extensions/vertx-http/deployment/pom.xml index c3db62b0bee6f..b9d45fac0cf5c 100644 --- a/extensions/vertx-http/deployment/pom.xml +++ b/extensions/vertx-http/deployment/pom.xml @@ -51,8 +51,7 @@ org.mvnpm importmap - - + io.quarkus.qute qute-core @@ -65,59 +64,7 @@ com.fasterxml.jackson.core jackson-databind - - - org.webjars - bootstrap - provided - - - org.webjars - bootstrap-multiselect - provided - - - org.webjars.npm - bootstrap-icons - provided - - - org.webjars - font-awesome - provided - - - org.webjars - jquery - provided - - - org.webjars - codemirror - provided - - - org.webjars - d3js - provided - - - org.webjars - chartjs - provided - - - org.webjars.npm - mermaid - provided - - - - * - * - - - + io.quarkus @@ -201,249 +148,6 @@ de.thetaphi forbiddenapis - - - - org.apache.maven.plugins - maven-dependency-plugin - - - install-ui - generate-sources - - unpack - - - - - - org.webjars - bootstrap - ${webjar.bootstrap.version} - jar - true - ${project.build.directory}/classes/dev-static/css/ - **/bootstrap.min.css, **/bootstrap.min.css.map - - - - - - org.webjars - bootstrap - ${webjar.bootstrap.version} - jar - true - ${project.build.directory}/classes/dev-static/js/ - **/bootstrap.bundle.min.js, **/bootstrap.bundle.min.js.map - - - - - - - org.webjars - bootstrap-multiselect - ${webjar.bootstrap-multiselect.version} - jar - true - ${project.build.directory}/classes/dev-static/js/ - **/bootstrap-multiselect.js - - - - - - org.webjars - bootstrap-multiselect - ${webjar.bootstrap-multiselect.version} - jar - true - ${project.build.directory}/classes/dev-static/css/ - **/bootstrap-multiselect.css - - - - - - org.webjars.npm - bootstrap-icons - ${webjar.bootstrap-icons.version} - jar - true - ${project.build.directory}/classes/dev-static/css/ - **/font/bootstrap-icons.css - - - - - - org.webjars.npm - bootstrap-icons - ${webjar.bootstrap-icons.version} - jar - true - ${project.build.directory}/classes/dev-static/css/fonts/ - **/font/fonts/ - - - - - - - org.webjars - jquery - ${webjar.jquery.version} - jar - true - ${project.build.directory}/classes/dev-static/js/ - **/jquery.min.js, **/jquery.min.js.map - - - - - - - org.webjars - font-awesome - ${webjar.font-awesome.version} - jar - true - ${project.build.directory}/classes/dev-static/fontawesome/css - **/css/all.min.css - - - - - - org.webjars - font-awesome - ${webjar.font-awesome.version} - jar - true - ${project.build.directory}/classes/dev-static/fontawesome/webfonts - **/webfonts/**.* - - - - - - - org.webjars - codemirror - ${webjar.codemirror.version} - jar - true - ${project.build.directory}/classes/dev-static/codemirror/lib - **/lib/**.js, **/lib/**.css - - - - - - org.webjars - codemirror - ${webjar.codemirror.version} - jar - true - ${project.build.directory}/classes/dev-static/codemirror/mode/properties - **/mode/properties/**.js - - - - - - org.webjars - codemirror - ${webjar.codemirror.version} - jar - true - ${project.build.directory}/classes/dev-static/codemirror/mode/yaml - **/mode/yaml/**.js - - - - - - org.webjars - codemirror - ${webjar.codemirror.version} - jar - true - ${project.build.directory}/classes/dev-static/codemirror/mode/javascript - **/mode/javascript/**.js - - - - - - org.webjars - codemirror - ${webjar.codemirror.version} - jar - true - ${project.build.directory}/classes/dev-static/codemirror/addon/hint - **/addon/hint/show-hint.js, **/addon/hint/show-hint.css - - - - - - org.webjars - codemirror - ${webjar.codemirror.version} - jar - true - ${project.build.directory}/classes/dev-static/codemirror/addon/selection - **/addon/selection/active-line.js - - - - - - - org.webjars.npm - mermaid - ${webjar.mermaid.version} - jar - true - ${project.build.directory}/classes/dev-static/js/ - **/mermaid.min.js, **/mermaid.min.js.map - - - - - - - org.webjars - d3js - ${webjar.d3js.version} - jar - true - ${project.build.directory}/classes/dev-static/js/ - **/d3.min.js - - - - - - - org.webjars - chartjs - ${webjar.chartjs.version} - jar - true - ${project.build.directory}/classes/dev-static/js/ - **/chart.min.js - - - - - - - - - diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/devui/deployment/DevUIProcessor.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/devui/deployment/DevUIProcessor.java index 77da57752799b..f8996848d6af6 100644 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/devui/deployment/DevUIProcessor.java +++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/devui/deployment/DevUIProcessor.java @@ -46,6 +46,7 @@ import io.quarkus.devui.deployment.extension.Codestart; import io.quarkus.devui.deployment.extension.Extension; import io.quarkus.devui.deployment.jsonrpc.DevUIDatabindCodec; +import io.quarkus.devui.runtime.DevUICORSFilter; import io.quarkus.devui.runtime.DevUIRecorder; import io.quarkus.devui.runtime.comms.JsonRpcRouter; import io.quarkus.devui.runtime.jsonrpc.JsonRpcMethod; @@ -70,7 +71,6 @@ import io.quarkus.vertx.http.deployment.webjar.WebJarBuildItem; import io.quarkus.vertx.http.deployment.webjar.WebJarResourcesFilter; import io.quarkus.vertx.http.deployment.webjar.WebJarResultsBuildItem; -import io.quarkus.vertx.http.runtime.devmode.DevConsoleCORSFilter; import io.smallrye.common.annotation.Blocking; import io.smallrye.common.annotation.NonBlocking; import io.smallrye.mutiny.Multi; @@ -140,7 +140,7 @@ void registerDevUiHandlers( if (devUIConfig.cors.enabled) { routeProducer.produce(nonApplicationRootPathBuildItem.routeBuilder() .orderedRoute(DEVUI + SLASH_ALL, -1 * FilterBuildItem.CORS) - .handler(new DevConsoleCORSFilter()) + .handler(new DevUICORSFilter()) .build()); } diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/devui/deployment/ide/IdeProcessor.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/devui/deployment/ide/IdeProcessor.java index a1b50e823ea2b..a957693941d38 100644 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/devui/deployment/ide/IdeProcessor.java +++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/devui/deployment/ide/IdeProcessor.java @@ -8,6 +8,8 @@ import java.util.Optional; import java.util.concurrent.TimeUnit; +import org.eclipse.microprofile.config.Config; +import org.eclipse.microprofile.config.ConfigProvider; import org.jboss.logging.Logger; import io.quarkus.deployment.IsDevelopment; @@ -18,6 +20,9 @@ import io.quarkus.dev.console.DevConsoleManager; import io.quarkus.devui.runtime.ide.IdeJsonRPCService; import io.quarkus.devui.spi.JsonRPCProvidersBuildItem; +import io.quarkus.utilities.OS; +import io.quarkus.vertx.http.deployment.HttpRootPathBuildItem; +import io.quarkus.vertx.http.deployment.NonApplicationRootPathBuildItem; /** * Processor for Ide interaction in Dev UI @@ -91,6 +96,52 @@ public void run() { return true; } + public static void openBrowser(HttpRootPathBuildItem rp, NonApplicationRootPathBuildItem np, String path, String host, + String port) { + if (path.startsWith("/q")) { + path = np.resolvePath(path.substring(3)); + } else { + path = rp.resolvePath(path.substring(1)); + } + + StringBuilder sb = new StringBuilder("http://"); + Config c = ConfigProvider.getConfig(); + sb.append(host); + sb.append(":"); + sb.append(port); + sb.append(path); + String url = sb.toString(); + + Runtime rt = Runtime.getRuntime(); + OS os = OS.determineOS(); + String[] command = null; + try { + switch (os) { + case MAC: + command = new String[] { "open", url }; + break; + case LINUX: + command = new String[] { "xdg-open", url }; + break; + case WINDOWS: + command = new String[] { "rundll32", "url.dll,FileProtocolHandler", url }; + break; + case OTHER: + log.error("Cannot launch browser on this operating system"); + } + if (command != null) { + rt.exec(command); + } + } catch (Exception e) { + log.debug("Failed to launch browser", e); + if (command != null) { + log.warn("Unable to open browser using command: '" + String.join(" ", command) + "'. Failure is: '" + + e.getMessage() + "'"); + } + } + + } + private boolean isNullOrEmpty(String arg) { return arg == null || arg.isBlank(); } diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/HttpRootPathBuildItem.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/HttpRootPathBuildItem.java index b5219b0166461..b09a57db097b5 100644 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/HttpRootPathBuildItem.java +++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/HttpRootPathBuildItem.java @@ -7,8 +7,8 @@ import io.quarkus.builder.item.SimpleBuildItem; import io.quarkus.deployment.util.UriNormalizationUtil; import io.quarkus.vertx.http.deployment.RouteBuildItem.RouteType; +import io.quarkus.vertx.http.deployment.devmode.ConfiguredPathInfo; import io.quarkus.vertx.http.deployment.devmode.NotFoundPageDisplayableEndpointBuildItem; -import io.quarkus.vertx.http.deployment.devmode.console.ConfiguredPathInfo; import io.quarkus.vertx.http.runtime.BasicRoute; import io.quarkus.vertx.http.runtime.HandlerType; import io.vertx.core.Handler; diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/NonApplicationRootPathBuildItem.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/NonApplicationRootPathBuildItem.java index 917e1f07da444..13643dbe5d563 100644 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/NonApplicationRootPathBuildItem.java +++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/NonApplicationRootPathBuildItem.java @@ -10,8 +10,8 @@ import io.quarkus.builder.item.SimpleBuildItem; import io.quarkus.deployment.builditem.LaunchModeBuildItem; import io.quarkus.deployment.util.UriNormalizationUtil; +import io.quarkus.vertx.http.deployment.devmode.ConfiguredPathInfo; import io.quarkus.vertx.http.deployment.devmode.NotFoundPageDisplayableEndpointBuildItem; -import io.quarkus.vertx.http.deployment.devmode.console.ConfiguredPathInfo; import io.quarkus.vertx.http.runtime.HandlerType; import io.quarkus.vertx.http.runtime.management.ManagementInterfaceBuildTimeConfig; import io.vertx.core.Handler; diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/RouteBuildItem.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/RouteBuildItem.java index 2fc29dad31396..7156e0db32b43 100644 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/RouteBuildItem.java +++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/RouteBuildItem.java @@ -9,8 +9,8 @@ import org.eclipse.microprofile.config.ConfigProvider; import io.quarkus.builder.item.MultiBuildItem; +import io.quarkus.vertx.http.deployment.devmode.ConfiguredPathInfo; import io.quarkus.vertx.http.deployment.devmode.NotFoundPageDisplayableEndpointBuildItem; -import io.quarkus.vertx.http.deployment.devmode.console.ConfiguredPathInfo; import io.quarkus.vertx.http.runtime.BasicRoute; import io.quarkus.vertx.http.runtime.HandlerType; import io.vertx.core.Handler; diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/ConfiguredPathInfo.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/ConfiguredPathInfo.java similarity index 96% rename from extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/ConfiguredPathInfo.java rename to extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/ConfiguredPathInfo.java index b19f44dfb769f..99c62a76dbda7 100644 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/ConfiguredPathInfo.java +++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/ConfiguredPathInfo.java @@ -1,4 +1,4 @@ -package io.quarkus.vertx.http.deployment.devmode.console; +package io.quarkus.vertx.http.deployment.devmode; import io.quarkus.deployment.builditem.LaunchModeBuildItem; import io.quarkus.runtime.TemplateHtmlBuilder; diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleFailedStartHandler.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/DevModeFailedStartHandler.java similarity index 61% rename from extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleFailedStartHandler.java rename to extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/DevModeFailedStartHandler.java index da733c5769dcf..3e2d4b4c13b42 100644 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleFailedStartHandler.java +++ b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/DevModeFailedStartHandler.java @@ -1,13 +1,12 @@ -package io.quarkus.vertx.http.deployment.devmode.console; +package io.quarkus.vertx.http.deployment.devmode; import io.quarkus.dev.config.CurrentConfig; import io.quarkus.dev.spi.DeploymentFailedStartHandler; import io.quarkus.devui.deployment.menu.ConfigurationProcessor; -public class DevConsoleFailedStartHandler implements DeploymentFailedStartHandler { +public class DevModeFailedStartHandler implements DeploymentFailedStartHandler { @Override public void handleFailedInitialStart() { - DevConsoleProcessor.initializeVirtual(); CurrentConfig.EDITOR = ConfigurationProcessor::updateConfig; } } diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsole.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsole.java deleted file mode 100644 index f311d3730a7e6..0000000000000 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsole.java +++ /dev/null @@ -1,248 +0,0 @@ -package io.quarkus.vertx.http.deployment.devmode.console; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Scanner; -import java.util.TreeMap; -import java.util.function.BiFunction; - -import org.eclipse.microprofile.config.Config; -import org.eclipse.microprofile.config.ConfigProvider; -import org.jboss.logging.Logger; -import org.yaml.snakeyaml.LoaderOptions; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.SafeConstructor; - -import io.netty.handler.codec.http.HttpHeaderNames; -import io.quarkus.builder.Version; -import io.quarkus.devconsole.runtime.spi.FlashScopeUtil; -import io.quarkus.maven.dependency.GACTV; -import io.quarkus.qute.Engine; -import io.quarkus.qute.Template; -import io.quarkus.qute.TemplateInstance; -import io.smallrye.common.classloader.ClassPathUtils; -import io.vertx.core.Handler; -import io.vertx.core.http.HttpHeaders; -import io.vertx.ext.web.RoutingContext; - -/** - * This is a Handler running in the Dev Vert.x instance (which is loaded by the Augmentation ClassLoader) - * and has access to build time stuff - */ -public class DevConsole implements Handler { - - private static final Logger log = Logger.getLogger(DevConsole.class); - - private static final String HTML_CONTENT_TYPE = "text/html; charset=UTF-8"; - - static final ThreadLocal currentExtension = new ThreadLocal<>(); - private static final Comparator> EXTENSION_COMPARATOR = Comparator - .comparing(m -> ((String) m.get("name"))); - - final Engine engine; - final Map> extensions = new HashMap<>(); - - final Map globalData = new HashMap<>(); - - final Config config = ConfigProvider.getConfig(); - final String devRootAppend; - - DevConsole(Engine engine, String httpRootPath, String frameworkRootPath) { - this.engine = engine; - // Both of these paths will end in slash - this.globalData.put("httpRootPath", httpRootPath); - this.globalData.put("frameworkRootPath", frameworkRootPath); - - // This includes the dev segment, but does not include a trailing slash (for append) - this.devRootAppend = frameworkRootPath + "dev-v1"; - this.globalData.put("devRootAppend", devRootAppend); - - this.globalData.put("quarkusVersion", Version.getVersion()); - this.globalData.put("applicationName", config.getOptionalValue("quarkus.application.name", String.class).orElse("")); - this.globalData.put("applicationVersion", - config.getOptionalValue("quarkus.application.version", String.class).orElse("")); - } - - private void initLazyState() { - if (extensions.isEmpty()) { - synchronized (extensions) { - if (extensions.isEmpty()) { - try { - final Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions())); - ClassPathUtils.consumeAsPaths("/META-INF/quarkus-extension.yaml", p -> { - try { - final String desc; - try (Scanner scanner = new Scanner(Files.newBufferedReader(p, StandardCharsets.UTF_8))) { - scanner.useDelimiter("\\A"); - desc = scanner.hasNext() ? scanner.next() : null; - } - if (desc == null) { - // should be an exception? - return; - } - final Map metadata = yaml.load(desc); - extensions.put(getExtensionNamespace(metadata), metadata); - } catch (IOException | RuntimeException e) { - // don't abort, just log, to prevent a single extension from breaking entire dev ui - log.error("Failed to process extension descriptor " + p.toUri(), e); - } - }); - this.globalData.put("configKeyMap", getConfigKeyMap()); - } catch (IOException x) { - throw new RuntimeException(x); - } - } - } - } - } - - @Override - public void handle(RoutingContext ctx) { - initLazyState(); - // Redirect /q/dev-v1 to /q/dev-v1/ - if (ctx.normalizedPath().length() == devRootAppend.length()) { - ctx.response().setStatusCode(302); - ctx.response().headers().set(HttpHeaders.LOCATION, devRootAppend + "/"); - ctx.response().end(); - return; - } - - String path = ctx.normalizedPath().substring(ctx.mountPoint().length() + 1); - if (path.isEmpty() || path.equals("/")) { - sendMainPage(ctx); - } else { - int nsIndex = path.indexOf("/"); - if (nsIndex == -1) { - ctx.response().setStatusCode(404).end(); - return; - } - String namespace = path.substring(0, nsIndex); - currentExtension.set(namespace); - Template devTemplate = engine.getTemplate(path); - if (devTemplate != null) { - String extName = getExtensionName(namespace); - ctx.response().setStatusCode(200).headers().set(HttpHeaderNames.CONTENT_TYPE, HTML_CONTENT_TYPE); - TemplateInstance devTemplateInstance = devTemplate - .data("currentExtensionName", extName) - .data("query-string", ctx.request().query()) - .data("flash", FlashScopeUtil.getFlash(ctx)) - .data("currentRequest", ctx.request()); - renderTemplate(ctx, devTemplateInstance); - } else { - ctx.next(); - } - } - } - - private Map> getConfigKeyMap() { - Map> ckm = new TreeMap<>(); - Collection> values = this.extensions.values(); - for (Map extension : values) { - if (extension.containsKey("metadata")) { - Map metadata = (Map) extension.get("metadata"); - if (metadata.containsKey("config")) { - List configKeys = (List) metadata.get("config"); - String name = (String) extension.get("name"); - ckm.put(name, configKeys); - } - } - } - return ckm; - } - - private String getExtensionName(String namespace) { - Map map = extensions.get(namespace); - if (map == null) - return null; - return (String) map.get("name"); - } - - protected void renderTemplate(RoutingContext event, TemplateInstance template) { - // Add some global variables - for (Map.Entry global : globalData.entrySet()) { - template.data(global.getKey(), global.getValue()); - } - - template.renderAsync().handle(new BiFunction() { - @Override - public Object apply(String s, Throwable throwable) { - if (throwable != null) { - event.fail(throwable); - } else { - event.response().end(s); - } - return null; - } - }); - } - - private void sendMainPage(RoutingContext event) { - final Template devTemplate = engine.getTemplate("index"); - if (devTemplate == null) { - throw new RuntimeException("Failed to locate the `index` template"); - } - List> actionableExtensions = new ArrayList<>(); - List> nonActionableExtensions = new ArrayList<>(); - for (Entry> entry : this.extensions.entrySet()) { - final String namespace = entry.getKey(); - final Map loaded = entry.getValue(); - @SuppressWarnings("unchecked") - final Map metadata = (Map) loaded.get("metadata"); - currentExtension.set(namespace); // needed because the template of the extension is going to be read - Template simpleTemplate = engine.getTemplate(namespace + "/embedded.html"); - boolean hasConsoleEntry = simpleTemplate != null; - boolean hasGuide = metadata.containsKey("guide"); - boolean hasConfig = metadata.containsKey("config"); - boolean isUnlisted = metadata.containsKey("unlisted") - && (metadata.get("unlisted").equals(true) || metadata.get("unlisted").equals("true")); - loaded.put("hasConsoleEntry", hasConsoleEntry); - loaded.put("hasGuide", hasGuide); - if (!isUnlisted || hasConsoleEntry || hasGuide || hasConfig) { - if (hasConsoleEntry) { - Map data = new HashMap<>(); - data.putAll(globalData); - data.put("urlbase", namespace); - String result = simpleTemplate.render(data); - loaded.put("_dev", result); - actionableExtensions.add(loaded); - } else { - nonActionableExtensions.add(loaded); - } - } - } - actionableExtensions.sort(EXTENSION_COMPARATOR); - nonActionableExtensions.sort(EXTENSION_COMPARATOR); - TemplateInstance instance = devTemplate.data("actionableExtensions", actionableExtensions) - .data("nonActionableExtensions", nonActionableExtensions).data("flash", FlashScopeUtil.getFlash(event)); - event.response().setStatusCode(200).headers().set(HttpHeaderNames.CONTENT_TYPE, HTML_CONTENT_TYPE); - renderTemplate(event, instance); - } - - private static String getExtensionNamespace(Map metadata) { - final String groupId; - final String artifactId; - final String artifact = (String) metadata.get("artifact"); - if (artifact == null) { - // trying quarkus 1.x format - groupId = (String) metadata.get("group-id"); - artifactId = (String) metadata.get("artifact-id"); - if (artifactId == null || groupId == null) { - throw new RuntimeException( - "Failed to locate 'artifact' or 'group-id' and 'artifact-id' among metadata keys " + metadata.keySet()); - } - } else { - final GACTV coords = GACTV.fromString(artifact); - groupId = coords.getGroupId(); - artifactId = coords.getArtifactId(); - } - return groupId + "." + artifactId; - } -} diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleHttpHandler.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleHttpHandler.java deleted file mode 100644 index 1d7271114a542..0000000000000 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleHttpHandler.java +++ /dev/null @@ -1,172 +0,0 @@ -package io.quarkus.vertx.http.deployment.devmode.console; - -import java.io.ByteArrayOutputStream; -import java.nio.channels.Channels; -import java.nio.channels.WritableByteChannel; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.function.Consumer; - -import org.jboss.logging.Logger; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.FileRegion; -import io.netty.handler.codec.http.DefaultHttpRequest; -import io.netty.handler.codec.http.DefaultLastHttpContent; -import io.netty.handler.codec.http.HttpContent; -import io.netty.handler.codec.http.HttpHeaderNames; -import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpResponse; -import io.netty.handler.codec.http.HttpVersion; -import io.netty.handler.codec.http.LastHttpContent; -import io.netty.util.ReferenceCountUtil; -import io.quarkus.dev.console.DevConsoleRequest; -import io.quarkus.dev.console.DevConsoleResponse; -import io.quarkus.netty.runtime.virtual.VirtualAddress; -import io.quarkus.netty.runtime.virtual.VirtualClientConnection; -import io.quarkus.netty.runtime.virtual.VirtualResponseHandler; -import io.quarkus.vertx.http.runtime.QuarkusHttpHeaders; - -/** - * The idea here is to dispatch the DevConsoleRequest into the Netty event loop that powers the Dev Vert.x instance. - * - * Although this is loaded by the Augmentation ClassLoader at build time, - * it however works because all the classes part its signature are loaded by the System ClassLoader - * which is the same for build steps and runtime code (DevConsoleRequest is a part of the devmode-spi which - * is a parent first dependency thus also loaded by the System ClassLoader). - */ -@SuppressWarnings("unused") -public class DevConsoleHttpHandler implements Consumer { - private static final Logger log = Logger.getLogger(DevConsoleHttpHandler.class); - public static VirtualAddress QUARKUS_DEV_CONSOLE = new VirtualAddress("quarkus-dev-console"); - - private static final int BUFFER_SIZE = 8096; - - @Override - public void accept(DevConsoleRequest request) { - try { - nettyDispatch(request); - } catch (Exception e) { - request.getResponse().completeExceptionally(e); - } - - } - - private class NettyResponseHandler implements VirtualResponseHandler { - ByteArrayOutputStream baos; - WritableByteChannel byteChannel; - final DevConsoleRequest request; - final DevConsoleResponse responseBuilder = new DevConsoleResponse(); - private volatile VirtualClientConnection connection; - - public NettyResponseHandler(DevConsoleRequest request) { - this.request = request; - } - - public CompletableFuture getFuture() { - return request.getResponse(); - } - - @Override - public void handleMessage(Object msg) { - try { - //log.info("Got message: " + msg.getClass().getName()); - - if (msg instanceof HttpResponse) { - HttpResponse res = (HttpResponse) msg; - responseBuilder.setStatus(res.status().code()); - - for (String name : res.headers().names()) { - responseBuilder.getHeaders().put(name, res.headers().getAll(name)); - } - } - if (msg instanceof HttpContent) { - HttpContent content = (HttpContent) msg; - int readable = content.content().readableBytes(); - if (baos == null && readable > 0) { - baos = createByteStream(); - } - for (int i = 0; i < readable; i++) { - baos.write(content.content().readByte()); - } - } - if (msg instanceof FileRegion) { - FileRegion file = (FileRegion) msg; - if (file.count() > 0 && file.transferred() < file.count()) { - if (baos == null) - baos = createByteStream(); - if (byteChannel == null) - byteChannel = Channels.newChannel(baos); - file.transferTo(byteChannel, file.transferred()); - } - } - if (msg instanceof LastHttpContent) { - if (baos != null) { - responseBuilder.setBody(baos.toByteArray()); - } - getFuture().complete(responseBuilder); - if (connection != null) { - connection.close(); - } - } - } catch (Throwable ex) { - getFuture().completeExceptionally(ex); - } finally { - if (msg != null) { - ReferenceCountUtil.release(msg); - } - } - } - - @Override - public void close() { - if (!getFuture().isDone()) { - getFuture().completeExceptionally(new RuntimeException("Connection closed")); - } - } - - public void setConnection(VirtualClientConnection connection) { - this.connection = connection; - } - - public VirtualClientConnection getConnection() { - return connection; - } - } - - private void nettyDispatch(DevConsoleRequest request) - throws Exception { - String uri = request.getUri(); - QuarkusHttpHeaders quarkusHeaders = new QuarkusHttpHeaders(); - DefaultHttpRequest nettyRequest = new DefaultHttpRequest(HttpVersion.HTTP_1_1, - HttpMethod.valueOf(request.getMethod()), uri, quarkusHeaders); - for (Map.Entry> i : request.getHeaders().entrySet()) { - nettyRequest.headers().add(i.getKey(), i.getValue()); - } - if (!nettyRequest.headers().contains(HttpHeaderNames.HOST)) { - nettyRequest.headers().add(HttpHeaderNames.HOST, "localhost"); - } - - HttpContent requestContent = LastHttpContent.EMPTY_LAST_CONTENT; - if (request.getBody() != null) { - ByteBuf body = Unpooled.wrappedBuffer(request.getBody()); - requestContent = new DefaultLastHttpContent(body); - } - NettyResponseHandler handler = new NettyResponseHandler(request); - VirtualClientConnection connection = VirtualClientConnection.connect(handler, QUARKUS_DEV_CONSOLE, - null); - handler.setConnection(connection); - - connection.sendMessage(nettyRequest); - connection.sendMessage(requestContent); - } - - private ByteArrayOutputStream createByteStream() { - ByteArrayOutputStream baos; - baos = new ByteArrayOutputStream(BUFFER_SIZE); - return baos; - } - -} diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleProcessor.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleProcessor.java deleted file mode 100644 index ed6d4d65c11a9..0000000000000 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevConsoleProcessor.java +++ /dev/null @@ -1,1034 +0,0 @@ -package io.quarkus.vertx.http.deployment.devmode.console; - -import java.io.File; -import java.io.IOException; -import java.io.Reader; -import java.io.StringReader; -import java.io.UncheckedIOException; -import java.net.URLConnection; -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.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.TimeUnit; -import java.util.function.Function; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -import org.eclipse.microprofile.config.Config; -import org.eclipse.microprofile.config.ConfigProvider; -import org.jboss.logging.Logger; - -import io.netty.bootstrap.ServerBootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelInitializer; -import io.netty.handler.codec.http.HttpHeaderNames; -import io.quarkus.bootstrap.classloading.ClassPathElement; -import io.quarkus.bootstrap.classloading.QuarkusClassLoader; -import io.quarkus.deployment.IsDevelopment; -import io.quarkus.deployment.annotations.BuildProducer; -import io.quarkus.deployment.annotations.BuildStep; -import io.quarkus.deployment.annotations.Consume; -import io.quarkus.deployment.annotations.ExecutionTime; -import io.quarkus.deployment.annotations.Produce; -import io.quarkus.deployment.annotations.Record; -import io.quarkus.deployment.builditem.ConfigDescriptionBuildItem; -import io.quarkus.deployment.builditem.LaunchModeBuildItem; -import io.quarkus.deployment.builditem.ServiceStartBuildItem; -import io.quarkus.deployment.builditem.ShutdownContextBuildItem; -import io.quarkus.deployment.console.ConsoleCommand; -import io.quarkus.deployment.console.ConsoleStateManager; -import io.quarkus.deployment.ide.EffectiveIdeBuildItem; -import io.quarkus.deployment.ide.Ide; -import io.quarkus.deployment.logging.LoggingSetupBuildItem; -import io.quarkus.deployment.pkg.builditem.BuildSystemTargetBuildItem; -import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem; -import io.quarkus.deployment.util.ArtifactInfoUtil; -import io.quarkus.dev.console.DevConsoleManager; -import io.quarkus.dev.spi.DevModeType; -import io.quarkus.devconsole.spi.DevConsoleRouteBuildItem; -import io.quarkus.devconsole.spi.DevConsoleRuntimeTemplateInfoBuildItem; -import io.quarkus.devconsole.spi.DevConsoleTemplateInfoBuildItem; -import io.quarkus.devconsole.spi.DevConsoleWebjarBuildItem; -import io.quarkus.devui.deployment.DevUIConfig; -import io.quarkus.maven.dependency.ArtifactKey; -import io.quarkus.maven.dependency.GACT; -import io.quarkus.netty.runtime.virtual.VirtualChannel; -import io.quarkus.netty.runtime.virtual.VirtualServerChannel; -import io.quarkus.qute.Engine; -import io.quarkus.qute.EngineBuilder; -import io.quarkus.qute.EvalContext; -import io.quarkus.qute.Expression; -import io.quarkus.qute.HtmlEscaper; -import io.quarkus.qute.NamespaceResolver; -import io.quarkus.qute.RawString; -import io.quarkus.qute.ReflectionValueResolver; -import io.quarkus.qute.ResultMapper; -import io.quarkus.qute.Results; -import io.quarkus.qute.TemplateException; -import io.quarkus.qute.TemplateLocator; -import io.quarkus.qute.TemplateNode.Origin; -import io.quarkus.qute.UserTagSectionHelper; -import io.quarkus.qute.ValueResolver; -import io.quarkus.qute.ValueResolvers; -import io.quarkus.qute.Variant; -import io.quarkus.runtime.TemplateHtmlBuilder; -import io.quarkus.utilities.OS; -import io.quarkus.vertx.http.deployment.BodyHandlerBuildItem; -import io.quarkus.vertx.http.deployment.FilterBuildItem; -import io.quarkus.vertx.http.deployment.HttpRootPathBuildItem; -import io.quarkus.vertx.http.deployment.NonApplicationRootPathBuildItem; -import io.quarkus.vertx.http.deployment.RouteBuildItem; -import io.quarkus.vertx.http.deployment.webjar.WebJarBuildItem; -import io.quarkus.vertx.http.deployment.webjar.WebJarResultsBuildItem; -import io.quarkus.vertx.http.runtime.devmode.DevConsoleCORSFilter; -import io.quarkus.vertx.http.runtime.devmode.DevConsoleFilter; -import io.quarkus.vertx.http.runtime.devmode.DevConsoleRecorder; -import io.quarkus.vertx.http.runtime.devmode.RedirectHandler; -import io.quarkus.vertx.http.runtime.devmode.RuntimeDevConsoleRoute; -import io.quarkus.vertx.http.runtime.management.ManagementInterfaceBuildTimeConfig; -import io.smallrye.common.vertx.VertxContext; -import io.smallrye.config.common.utils.StringUtil; -import io.vertx.core.Handler; -import io.vertx.core.Vertx; -import io.vertx.core.VertxOptions; -import io.vertx.core.http.HttpMethod; -import io.vertx.core.http.HttpServerOptions; -import io.vertx.core.http.HttpServerRequest; -import io.vertx.core.http.impl.Http1xServerConnection; -import io.vertx.core.impl.ContextInternal; -import io.vertx.core.impl.EventLoopContext; -import io.vertx.core.impl.VertxBuilder; -import io.vertx.core.impl.VertxInternal; -import io.vertx.core.impl.VertxThread; -import io.vertx.core.impl.transports.JDKTransport; -import io.vertx.core.net.impl.VertxHandler; -import io.vertx.core.spi.VertxThreadFactory; -import io.vertx.ext.web.Route; -import io.vertx.ext.web.Router; -import io.vertx.ext.web.RoutingContext; -import io.vertx.ext.web.handler.BodyHandler; - -public class DevConsoleProcessor { - - private static final Logger log = Logger.getLogger(DevConsoleProcessor.class); - - private static final GACT DEVCONSOLE_WEBJAR_ARTIFACT_KEY = new GACT("io.quarkus", "quarkus-vertx-http-deployment", null, - "jar"); - private static final String DEVCONSOLE_WEBJAR_STATIC_RESOURCES_PATH = "dev-static/"; - private static final Object EMPTY = new Object(); - - // FIXME: config, take from Qute? - private static final String[] suffixes = new String[] { "html", "txt" }; - protected static volatile ServerBootstrap virtualBootstrap; - protected static volatile Vertx devConsoleVertx; - protected static volatile Channel channel; - static Router router; - static Router mainRouter; - - public static void initializeVirtual() { - if (virtualBootstrap != null) { - return; - } - devConsoleVertx = initializeDevConsoleVertx(); - VertxInternal vertx = (VertxInternal) devConsoleVertx; - QuarkusClassLoader ccl = (QuarkusClassLoader) DevConsoleProcessor.class.getClassLoader(); - ccl.addCloseTask(new Runnable() { - @Override - public void run() { - virtualBootstrap = null; - if (channel != null) { - try { - channel.close().sync(); - } catch (InterruptedException e) { - throw new RuntimeException("failed to close virtual http"); - } - } - if (devConsoleVertx != null) { - devConsoleVertx.close(); - devConsoleVertx = null; - } - } - }); - virtualBootstrap = new ServerBootstrap(); - virtualBootstrap.group(vertx.getEventLoopGroup()) - .channel(VirtualServerChannel.class) - .handler(new ChannelInitializer() { - @Override - public void initChannel(VirtualServerChannel ch) throws Exception { - //ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO)); - } - }) - .childHandler(new ChannelInitializer() { - @Override - public void initChannel(VirtualChannel ch) throws Exception { - // Vert.x 4 Migration: Verify this behavior - EventLoopContext context = vertx.createEventLoopContext(); - - VertxHandler handler = VertxHandler.create(chctx -> { - Http1xServerConnection connection = new Http1xServerConnection( - () -> (ContextInternal) VertxContext.getOrCreateDuplicatedContext(context), - null, - new HttpServerOptions(), - chctx, - context, - "localhost", - null); - connection.handler(new Handler() { - @Override - public void handle(HttpServerRequest event) { - mainRouter.handle(event); - } - }); - return connection; - }); - ch.pipeline().addLast("handler", handler); - } - }); - - // Start the server. - try { - ChannelFuture future = virtualBootstrap.bind(DevConsoleHttpHandler.QUARKUS_DEV_CONSOLE); - future.sync(); - channel = future.channel(); - } catch (InterruptedException e) { - throw new RuntimeException("failed to bind virtual http"); - } - - } - - /** - * Boots the Vert.x instance used by the DevConsole, - * applying some minimal tuning and customizations. - * - * @return the initialized Vert.x instance - */ - private static Vertx initializeDevConsoleVertx() { - final VertxOptions vertxOptions = new VertxOptions(); - //Smaller than default, but larger than 1 to be on the safe side. - int POOL_SIZE = 2; - vertxOptions.setEventLoopPoolSize(POOL_SIZE); - vertxOptions.setWorkerPoolSize(POOL_SIZE); - vertxOptions.getMetricsOptions().setEnabled(false); - //Not good for development: - vertxOptions.getFileSystemOptions().setFileCachingEnabled(false); - vertxOptions.getFileSystemOptions().setClassPathResolvingEnabled(false); - VertxBuilder builder = new VertxBuilder(vertxOptions); - builder.threadFactory(new VertxThreadFactory() { - @Override - public VertxThread newVertxThread(Runnable target, String name, boolean worker, long maxExecTime, - TimeUnit maxExecTimeUnit) { - //Customize the Thread names so to not conflict with the names generated by the main Quarkus Vert.x instance - return new VertxThread(target, "[DevConsole]" + name, worker, maxExecTime, maxExecTimeUnit); - } - }); - builder.findTransport(JDKTransport.INSTANCE); - builder.init(); - return builder.vertx(); - } - - protected static void newRouter(Engine engine, - NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem) { - - // "/" or "/myroot/" - String httpRootPath = nonApplicationRootPathBuildItem.getNormalizedHttpRootPath(); - // "/" or "/myroot/" or "/q/" or "/myroot/q/" - String frameworkRootPath = nonApplicationRootPathBuildItem.getNonApplicationRootPath(); - - Handler errorHandler = new Handler() { - @Override - public void handle(RoutingContext event) { - String message = "Dev console request failed"; - log.error(message, event.failure()); - event.response().headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html; charset=utf-8"); - event.response().end( - new TemplateHtmlBuilder("Internal Server Error", message, message).stack(event.failure()).toString()); - } - }; - router = Router.router(devConsoleVertx); - router.errorHandler(500, errorHandler); - - router.route() - .order(Integer.MIN_VALUE) - .handler(new FlashScopeHandler()); - - router.route().method(HttpMethod.GET) - .order(Integer.MIN_VALUE + 1) - .handler(new DevConsole(engine, httpRootPath, frameworkRootPath)); - mainRouter = Router.router(devConsoleVertx); - mainRouter.errorHandler(500, errorHandler); - mainRouter.route(nonApplicationRootPathBuildItem.resolvePath("dev-v1*")).subRouter(router); - } - - @BuildStep(onlyIf = IsDevelopment.class) - public ServiceStartBuildItem buildTimeTemplates(List items, - CurateOutcomeBuildItem curateOutcomeBuildItem) { - Map> results = new HashMap<>(); - for (DevConsoleTemplateInfoBuildItem i : items) { - Entry groupAndArtifact = i.groupIdAndArtifactId(curateOutcomeBuildItem); - Map map = results.computeIfAbsent(groupAndArtifact.getKey() + "." + groupAndArtifact.getValue(), - (s) -> new HashMap<>()); - map.put(i.getName(), i.getObject()); - } - DevConsoleManager.setTemplateInfo(results); - return null; - } - - @BuildStep - DevTemplateVariantsBuildItem collectTemplateVariants(List templatePaths) throws IOException { - Set allPaths = templatePaths.stream().map(DevTemplatePathBuildItem::getPath).collect(Collectors.toSet()); - // item -> [item.html, item.txt] - // ItemResource/item -> -> [ItemResource/item.html, ItemResource/item.xml] - Map> baseToVariants = new HashMap<>(); - for (String path : allPaths) { - int idx = path.lastIndexOf('.'); - if (idx != -1) { - String base = path.substring(0, idx); - List variants = baseToVariants.get(base); - if (variants == null) { - variants = new ArrayList<>(); - baseToVariants.put(base, variants); - } - variants.add(path); - } - } - return new DevTemplateVariantsBuildItem(baseToVariants); - } - - @BuildStep(onlyIf = IsDevelopment.class) - @Record(ExecutionTime.RUNTIME_INIT) - public void runtimeTemplates(List items, DevConsoleRecorder recorder, - List gate) { - for (DevConsoleRuntimeTemplateInfoBuildItem i : items) { - recorder.addInfo(i.getGroupId(), i.getArtifactId(), i.getName(), i.getObject()); - } - recorder.initConfigFun(); - } - - @Consume(LoggingSetupBuildItem.class) - @BuildStep(onlyIf = IsDevelopment.class) - public ServiceStartBuildItem setupDeploymentSideHandling(List devTemplatePaths, - CurateOutcomeBuildItem curateOutcomeBuildItem, - BuildSystemTargetBuildItem buildSystemTargetBuildItem, - Optional effectiveIdeBuildItem, - List allRoutes, - List routes, - NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem, - ManagementInterfaceBuildTimeConfig managementInterfaceBuildTimeConfig, - List configDescriptionBuildItems, - LaunchModeBuildItem launchModeBuildItem) { - if (launchModeBuildItem.getDevModeType().orElse(null) != DevModeType.LOCAL) { - return null; - } - - initializeVirtual(); - Engine quteEngine = buildEngine(devTemplatePaths, - allRoutes, - buildSystemTargetBuildItem, - effectiveIdeBuildItem, - nonApplicationRootPathBuildItem, - managementInterfaceBuildTimeConfig, - configDescriptionBuildItems, - launchModeBuildItem); - newRouter(quteEngine, nonApplicationRootPathBuildItem); - - for (DevConsoleRouteBuildItem i : routes) { - Entry groupAndArtifact = i.groupIdAndArtifactId(curateOutcomeBuildItem); - // deployment side handling - if (i.isDeploymentSide()) { - Route route = router - .route("/" + groupAndArtifact.getKey() + "." + groupAndArtifact.getValue() + "/" + i.getPath()); - if (i.getMethod() != null) { - route = route.method(HttpMethod.valueOf(i.getMethod())); - } - if (i.isBodyHandlerRequired()) { - route.handler(BodyHandler.create()); - } - if (i.isBlockingHandler()) { - route.blockingHandler(i.getHandler()); - } else { - route.handler(i.getHandler()); - } - } - } - - return null; - } - - @BuildStep(onlyIf = IsDevelopment.class) - public WebJarBuildItem setupWebJar( - LaunchModeBuildItem launchModeBuildItem) { - if (launchModeBuildItem.getDevModeType().orElse(null) != DevModeType.LOCAL) { - return null; - } - return WebJarBuildItem.builder().artifactKey(DEVCONSOLE_WEBJAR_ARTIFACT_KEY) // - .root(DEVCONSOLE_WEBJAR_STATIC_RESOURCES_PATH) // - .build(); - } - - @BuildStep(onlyIf = IsDevelopment.class) - public void setupDevConsoleWebjar( - List devConsoleWebjarBuildItems, - BuildProducer webJarBuildItemBuildProducer, - LaunchModeBuildItem launchModeBuildItem) { - if (launchModeBuildItem.getDevModeType().orElse(null) != DevModeType.LOCAL) { - return; - } - for (DevConsoleWebjarBuildItem devConsoleWebjar : devConsoleWebjarBuildItems) { - webJarBuildItemBuildProducer.produce(WebJarBuildItem.builder() - .artifactKey(devConsoleWebjar.getArtifactKey()) - .root(devConsoleWebjar.getRoot()) - .useDefaultQuarkusBranding(devConsoleWebjar.getUseDefaultQuarkusBranding()) - .onlyCopyNonArtifactFiles(devConsoleWebjar.getOnlyCopyNonArtifactFiles()) - .build()); - } - } - - @Record(ExecutionTime.RUNTIME_INIT) - @BuildStep(onlyIf = IsDevelopment.class) - public void setupDevConsoleRoutes( - List devConsoleWebjarBuildItems, - DevConsoleRecorder recorder, - NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem, - ShutdownContextBuildItem shutdownContext, - BuildProducer routeBuildItemBuildProducer, - WebJarResultsBuildItem webJarResultsBuildItem) { - - for (DevConsoleWebjarBuildItem webjarBuildItem : devConsoleWebjarBuildItems) { - WebJarResultsBuildItem.WebJarResult result = webJarResultsBuildItem.byArtifactKey(webjarBuildItem.getArtifactKey()); - if (result == null) { - continue; - } - routeBuildItemBuildProducer.produce(nonApplicationRootPathBuildItem.routeBuilder() - .route("dev-v1/" + webjarBuildItem.getRouteRoot() + "/*") - .handler(recorder.fileSystemStaticHandler(result.getWebRootConfigurations(), shutdownContext)) - .build()); - } - } - - @Record(ExecutionTime.RUNTIME_INIT) - @Consume(LoggingSetupBuildItem.class) - @BuildStep(onlyIf = IsDevelopment.class) - public void setupDevConsoleRoutes( - DevUIConfig devUIConfig, - DevConsoleRecorder recorder, - List routes, - NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem, - ShutdownContextBuildItem shutdownContext, - BuildProducer routeBuildItemBuildProducer, - WebJarResultsBuildItem webJarResultsBuildItem, - CurateOutcomeBuildItem curateOutcomeBuildItem, - BodyHandlerBuildItem bodyHandlerBuildItem) { - - WebJarResultsBuildItem.WebJarResult result = webJarResultsBuildItem.byArtifactKey(DEVCONSOLE_WEBJAR_ARTIFACT_KEY); - - if (result == null) { - return; - } - - routeBuildItemBuildProducer.produce(nonApplicationRootPathBuildItem.routeBuilder() - .route("dev-v1/resources/*") - .handler(recorder.fileSystemStaticHandler( - result.getWebRootConfigurations(), shutdownContext)) - .build()); - - for (DevConsoleRouteBuildItem i : routes) { - Entry groupAndArtifact = i.groupIdAndArtifactId(curateOutcomeBuildItem); - // if the handler is a proxy, then that means it's been produced by a recorder and therefore belongs in the regular runtime Vert.x instance - // otherwise this is handled in the setupDeploymentSideHandling method - if (!i.isDeploymentSide()) { - NonApplicationRootPathBuildItem.Builder builder = nonApplicationRootPathBuildItem.routeBuilder() - .routeFunction( - "dev-v1/" + groupAndArtifact.getKey() + "." + groupAndArtifact.getValue() + "/" + i.getPath(), - new RuntimeDevConsoleRoute(i.getMethod(), - i.isBodyHandlerRequired() ? bodyHandlerBuildItem.getHandler() : null)); - if (i.isBlockingHandler()) { - builder.blockingRoute(); - } - builder.handler(i.getHandler()); - routeBuildItemBuildProducer.produce(builder.build()); - } - } - - if (devUIConfig.cors.enabled) { - routeBuildItemBuildProducer.produce(nonApplicationRootPathBuildItem.routeBuilder() - .orderedRoute("dev-v1/*", -1 * FilterBuildItem.CORS) - .handler(new DevConsoleCORSFilter()) - .build()); - } - - DevConsoleManager.registerHandler(new DevConsoleHttpHandler()); - //must be last so the above routes have precedence - routeBuildItemBuildProducer.produce(nonApplicationRootPathBuildItem.routeBuilder() - .route("dev-v1/*") - .handler(new DevConsoleFilter()) - .build()); - routeBuildItemBuildProducer.produce(nonApplicationRootPathBuildItem.routeBuilder() - .route("dev-v1") - .displayOnNotFoundPage("Dev UI (v1)") - .handler(new RedirectHandler()) - .build()); - } - - @BuildStep - void builder(Optional effectiveIdeBuildItem, BuildProducer producer) { - if (effectiveIdeBuildItem.isPresent()) { - producer.produce(new DevConsoleRouteBuildItem("openInIDE", "POST", - new OpenIdeHandler(effectiveIdeBuildItem.get().getIde()))); - } - } - - static volatile ConsoleStateManager.ConsoleContext context; - - @Produce(ServiceStartBuildItem.class) - @BuildStep() - void setupConsole(HttpRootPathBuildItem rp, NonApplicationRootPathBuildItem np, LaunchModeBuildItem launchModeBuildItem) { - if (launchModeBuildItem.getDevModeType().orElse(null) != DevModeType.LOCAL) { - return; - } - if (context == null) { - context = ConsoleStateManager.INSTANCE.createContext("HTTP"); - } - Config c = ConfigProvider.getConfig(); - String host = c.getOptionalValue("quarkus.http.host", String.class).orElse("localhost"); - String port = c.getOptionalValue("quarkus.http.port", String.class).orElse("8080"); - context.reset( - new ConsoleCommand('w', "Open the application in a browser", null, () -> openBrowser(rp, np, "/", host, port)), - new ConsoleCommand('d', "Open the Dev UI in a browser", null, () -> openBrowser(rp, np, "/q/dev", host, port))); - } - - public static void openBrowser(HttpRootPathBuildItem rp, NonApplicationRootPathBuildItem np, String path, String host, - String port) { - if (path.startsWith("/q")) { - path = np.resolvePath(path.substring(3)); - } else { - path = rp.resolvePath(path.substring(1)); - } - - StringBuilder sb = new StringBuilder("http://"); - Config c = ConfigProvider.getConfig(); - sb.append(host); - sb.append(":"); - sb.append(port); - sb.append(path); - String url = sb.toString(); - - Runtime rt = Runtime.getRuntime(); - OS os = OS.determineOS(); - String[] command = null; - try { - switch (os) { - case MAC: - command = new String[] { "open", url }; - break; - case LINUX: - command = new String[] { "xdg-open", url }; - break; - case WINDOWS: - command = new String[] { "rundll32", "url.dll,FileProtocolHandler", url }; - break; - case OTHER: - log.error("Cannot launch browser on this operating system"); - } - if (command != null) { - rt.exec(command); - } - } catch (Exception e) { - log.debug("Failed to launch browser", e); - if (command != null) { - log.warn("Unable to open browser using command: '" + String.join(" ", command) + "'. Failure is: '" - + e.getMessage() + "'"); - } - } - - } - - private Engine buildEngine(List devTemplatePaths, - List allRoutes, - BuildSystemTargetBuildItem buildSystemTargetBuildItem, - Optional effectiveIdeBuildItem, - NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem, - ManagementInterfaceBuildTimeConfig managementInterfaceBuildTimeConfig, - List configDescriptionBuildItems, - LaunchModeBuildItem launchModeBuildItem) { - EngineBuilder builder = Engine.builder().addDefaults(); - - // Escape some characters for HTML templates - builder.addResultMapper(new HtmlEscaper(List.of(Variant.TEXT_HTML))); - - builder.strictRendering(true) - .addValueResolver(new ReflectionValueResolver()) - .addValueResolver(new JsonObjectValueResolver()) - .addValueResolver(new MultiMapValueResolver()) - .addValueResolver(ValueResolvers.rawResolver()) - .addNamespaceResolver(NamespaceResolver.builder("ideInfo") - .resolve(new IdeInfoContextFunction(buildSystemTargetBuildItem, effectiveIdeBuildItem, - launchModeBuildItem)) - .build()) - .addNamespaceResolver(NamespaceResolver.builder("info").resolve(ctx -> { - String ext = DevConsole.currentExtension.get(); - if (ext == null) { - return Results.NotFound.from(ctx); - } - Map map = DevConsoleManager.getTemplateInfo().get(ext); - if (map == null) { - return Results.NotFound.from(ctx); - } - Object result = map.get(ctx.getName()); - return result == null ? Results.NotFound.from(ctx) : result; - }).build()); - - // Create map of resolved paths - Map resolvedPaths = new HashMap<>(); - for (RouteBuildItem item : allRoutes) { - ConfiguredPathInfo resolvedPathBuildItem = item.getConfiguredPathInfo(); - if (resolvedPathBuildItem != null) { - String path = resolvedPathBuildItem.getEndpointPath(nonApplicationRootPathBuildItem, - managementInterfaceBuildTimeConfig, launchModeBuildItem); - resolvedPaths.put(resolvedPathBuildItem.getName(), path); - } - } - - Map defaultValues = getDefaultValues(configDescriptionBuildItems); - - // {config:property('quarkus.lambda.handler')} - // {config:http-path('quarkus.smallrye-graphql.ui.root-path')} - // Note that the output value is always string! - builder.addNamespaceResolver(NamespaceResolver.builder("config").resolveAsync(ctx -> { - List params = ctx.getParams(); - if (params.size() != 1 || (!ctx.getName().equals("property") && !ctx.getName().equals("http-path"))) { - return Results.notFound(ctx); - } - if (ctx.getName().equals("http-path")) { - return ctx.evaluate(params.get(0)).thenCompose(propertyName -> { - String value = resolvedPaths.get(propertyName.toString()); - return CompletableFuture.completedFuture(value != null ? value : Results.NotFound.from(ctx)); - }); - } else { - return ctx.evaluate(params.get(0)).thenCompose(propertyName -> { - // Use the function stored in the DevConsoleRecorder to make sure the config is obtained using the correct TCCL - Function> configFun = DevConsoleManager.getGlobal("devui-config-fun"); - String val = configFun.apply(propertyName.toString()).orElse(defaultValues.get(propertyName.toString())); - return CompletableFuture.completedFuture(val != null ? val : Results.NotFound.from(ctx)); - }); - } - }).build()); - - // JavaDoc formatting - builder.addValueResolver(new JavaDocResolver()); - - // Config/System property -> Environment variable - builder.addValueResolver(new PropertyToEnvVarConverter()); - - // Add templates and tags - Map templates = new HashMap<>(); - for (DevTemplatePathBuildItem devTemplatePath : devTemplatePaths) { - templates.put(devTemplatePath.getPath(), devTemplatePath.getContents()); - if (devTemplatePath.isTag()) { - // Strip suffix, item.html -> item - String tagName = devTemplatePath.getTagName(); - builder.addSectionHelper(new UserTagSectionHelper.Factory(tagName, devTemplatePath.getPath())); - } - } - builder.addLocator(id -> locateTemplate(id, templates)); - - builder.addResultMapper(new ResultMapper() { - @Override - public int getPriority() { - // The priority must be higher than the one used for HtmlEscaper - return 10; - } - - @Override - public boolean appliesTo(Origin origin, Object result) { - return Results.isNotFound(result); - } - - @Override - public String map(Object result, Expression expression) { - Origin origin = expression.getOrigin(); - throw new TemplateException(origin, - String.format("Property not found in expression {%s} in template %s on line %s", - expression.toOriginalString(), - origin.getTemplateId(), origin.getLine())); - } - }); - builder.addResultMapper(new ResultMapper() { - @Override - public int getPriority() { - // The priority must be higher than the one used for HtmlEscaper - return 10; - } - - @Override - public boolean appliesTo(Origin origin, Object result) { - return result.equals(EMPTY); - } - - @Override - public String map(Object result, Expression expression) { - return "<>"; - } - }); - - Engine engine = builder.build(); - - // preload all templates - for (DevTemplatePathBuildItem devTemplatePath : devTemplatePaths) { - if (!devTemplatePath.isTag()) { - engine.getTemplate(devTemplatePath.getPath()); - } - } - return engine; - } - - private Map getDefaultValues(List configDescriptionBuildItems) { - Map defaultValues = new HashMap<>(); - - for (ConfigDescriptionBuildItem configDescriptionBuildItem : configDescriptionBuildItems) { - if (configDescriptionBuildItem.getDefaultValue() != null) { - defaultValues.put(configDescriptionBuildItem.getPropertyName(), configDescriptionBuildItem.getDefaultValue()); - } - } - return defaultValues; - } - - private static Optional locateTemplate(String id, Map templates) { - String template = templates.get(id); - if (template == null) { - // Try path with suffixes - for (String suffix : suffixes) { - id = id + "." + suffix; - template = templates.get(id); - if (template != null) { - break; - } - } - } - - if (template == null) - return Optional.empty(); - - String templateName = id; - String finalTemplate = template; - return Optional.of(new TemplateLocator.TemplateLocation() { - @Override - public Reader read() { - return new StringReader(finalTemplate); - } - - @Override - public Optional getVariant() { - Variant variant = null; - String fileName = templateName; - int slashIdx = fileName.lastIndexOf('/'); - if (slashIdx != -1) { - fileName = fileName.substring(slashIdx, fileName.length()); - } - int dotIdx = fileName.lastIndexOf('.'); - if (dotIdx != -1) { - String suffix = fileName.substring(dotIdx + 1, fileName.length()); - if (suffix.equalsIgnoreCase("json")) { - variant = Variant.forContentType(Variant.APPLICATION_JSON); - } else { - String contentType = URLConnection.getFileNameMap().getContentTypeFor(fileName); - if (contentType != null) { - variant = Variant.forContentType(contentType); - } - } - } - return Optional.ofNullable(variant); - } - }); - } - - @BuildStep - void collectTemplates(BuildProducer devTemplatePaths) { - for (ClassPathElement pe : QuarkusClassLoader.getElements("dev-templates", false)) { - scanTemplates(pe, devTemplatePaths); - } - } - - private void scanTemplates(ClassPathElement cpe, BuildProducer devTemplatePaths) { - final ArtifactKey key = cpe.getDependencyKey(); - if (key == null) { - return; - } - String prefix; - // don't move stuff for our "root" dev console artifact, since it includes the main template - if (key.getArtifactId().equals("quarkus-vertx-http-deployment") && key.getGroupId().equals("io.quarkus")) { - prefix = ""; - } else { - final StringBuilder sb = new StringBuilder() - .append(key.getGroupId()).append('.'); - if (key.getArtifactId().endsWith(ArtifactInfoUtil.DEPLOYMENT)) { - sb.append( - key.getArtifactId().substring(0, key.getArtifactId().length() - ArtifactInfoUtil.DEPLOYMENT.length())); - } else { - sb.append(key.getArtifactId()); - } - prefix = sb.append('/').toString(); - } - cpe.apply(tree -> { - final Path devTemplatesPath = tree.getPath("dev-templates"); - try { - Files.walkFileTree(devTemplatesPath, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - String contents = Files.readString(file); - // don't move tags yet, since we don't know how to use them afterwards - String relativePath = devTemplatesPath.relativize(file).toString(); - String correctedPath; - if (File.separatorChar == '\\') { - relativePath = relativePath.replace('\\', '/'); - } - if (relativePath.startsWith(DevTemplatePathBuildItem.TAGS)) { - correctedPath = relativePath; - } else { - correctedPath = prefix + relativePath; - } - devTemplatePaths.produce(new DevTemplatePathBuildItem(correctedPath, contents)); - return super.visitFile(file, attrs); - } - }); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - return null; - }); - } - - /** - * Convert a config/system property name to an environment variable name - */ - private static final class PropertyToEnvVarConverter implements ValueResolver { - - @Override - public boolean appliesTo(EvalContext context) { - return context.getBase() instanceof String && context.getName().equals("toEnvVar"); - } - - @Override - public CompletionStage resolve(EvalContext context) { - return CompletableFuture.completedFuture( - StringUtil - .replaceNonAlphanumericByUnderscores(context.getBase().toString()) - .toUpperCase()); - } - } - - public static class JavaDocResolver implements ValueResolver { - - private final Pattern codePattern = Pattern.compile("(\\{@code )([^}]+)(\\})"); - private final Pattern linkPattern = Pattern.compile("(\\{@link )([^}]+)(\\})"); - - @Override - public boolean appliesTo(EvalContext context) { - return context.getBase() instanceof String && context.getName().equals("fmtJavadoc"); - } - - @Override - public CompletionStage resolve(EvalContext context) { - String val = context.getBase().toString(); - // Replace {@code} and {@link} - val = codePattern.matcher(val).replaceAll("$2"); - val = linkPattern.matcher(val).replaceAll("$2"); - // Add br before @see and @deprecated - val = val.replace("@see", "
@see").replace("@deprecated", - "
@deprecated"); - // No need to escape special characters - return CompletableFuture.completedFuture(new RawString(val)); - } - } - - private static class DetectPackageFileVisitor extends SimpleFileVisitor { - private final List paths; - - public DetectPackageFileVisitor(List paths) { - this.paths = paths; - } - - @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { - boolean hasRegularFiles = false; - File[] files = dir.toFile().listFiles(); - if (files != null) { - for (File file : files) { - if (file.isFile()) { - hasRegularFiles = true; - break; - } - } - } - if (hasRegularFiles) { - paths.add(dir.toAbsolutePath().toString()); - } - return FileVisitResult.CONTINUE; - } - } - - private static class IdeInfoContextFunction implements Function { - - private static final String[] SUPPORTED_LANGS = { "java", "kotlin" }; - - private final Optional effectiveIdeBuildItem; - private final boolean disable; - - public IdeInfoContextFunction(BuildSystemTargetBuildItem buildSystemTargetBuildItem, - Optional effectiveIdeBuildItem, - LaunchModeBuildItem launchModeBuildItem) { - this.effectiveIdeBuildItem = effectiveIdeBuildItem; - disable = launchModeBuildItem.getDevModeType().orElse(DevModeType.LOCAL) != DevModeType.LOCAL; - } - - @Override - public Object apply(EvalContext ctx) { - String ctxName = ctx.getName(); - - List sourcesDir = DevConsoleManager.getHotReplacementContext().getSourcesDir(); - if (ctxName.endsWith("sourcePackages")) { - if (disable) { - return Collections.emptyList(); // we need this here because the result needs to be iterable - } - Map> sourcePackagesByLang = new HashMap<>(); - - for (Path sourcePaths : sourcesDir) { - String lang = sourcePaths.getFileName().toString(); - List packages = sourcePackagesForRoot(sourcePaths); - if (!packages.isEmpty()) { - // The `replace` is used to avoid invalid JavaScript identifier (using `-`) - // It happens when using Gradle and extensions generating code (Avro, gRPC...) - // See https://github.com/quarkusio/quarkus/issues/30288. - sourcePackagesByLang.put(lang.replace("-", "_"), packages); - } - } - return sourcePackagesByLang; - } - if (ctxName.endsWith("locationPackages")) { - if (disable) { - return Collections.emptyList(); // we need this here because the result needs to be iterable - } - Map> sourcePackagesByDir = new HashMap<>(); - - for (Path sourcePaths : sourcesDir) { - List packages = sourcePackagesForRoot(sourcePaths); - if (!packages.isEmpty()) { - sourcePackagesByDir.put(sourcePaths.toAbsolutePath().toString().replace("\\", "/"), packages); - } - } - return sourcePackagesByDir; - } - if (disable) { // all the other values are Strings - return EMPTY; - } - - switch (ctxName) { - case "ideLinkType": - if (!effectiveIdeBuildItem.isPresent()) { - return "none"; - } - return effectiveIdeBuildItem.get().getIde().equals(Ide.VSCODE) ? "client" : "server"; - case "ideClientLinkFormat": - if (!effectiveIdeBuildItem.isPresent()) { - return "unused"; - } - if (effectiveIdeBuildItem.get().getIde() == Ide.VSCODE) { - return "vscode://file/{0}:{1}"; - } else { - return "unused"; - } - case "ideServerLinkEndpoint": - if (!effectiveIdeBuildItem.isPresent()) { - return "unused"; - } - return "/io.quarkus.quarkus-vertx-http/openInIDE"; - } - return Results.notFound(ctx); - } - - /** - * Return the most general packages used in the application - *

- * TODO: this likely covers almost all typical use cases, but probably needs some tweaks for extreme corner cases - */ - private List sourcePackagesForRoot(Path langPath) { - if (!Files.exists(langPath)) { - return Collections.emptyList(); - } - File[] rootFiles = langPath.toFile().listFiles(); - List rootPackages = new ArrayList<>(1); - if (rootFiles != null) { - for (File rootFile : rootFiles) { - if (rootFile.isDirectory()) { - rootPackages.add(rootFile.toPath()); - } - } - } - if (rootPackages.isEmpty()) { - return List.of(""); - } - List result = new ArrayList<>(rootPackages.size()); - for (Path rootPackage : rootPackages) { - List paths = new ArrayList<>(); - SimpleFileVisitor simpleFileVisitor = new DetectPackageFileVisitor(paths); - try { - Files.walkFileTree(rootPackage, simpleFileVisitor); - if (paths.isEmpty()) { - continue; - } - String commonPath = commonPath(paths); - String rootPackageStr = commonPath.replace(langPath.toAbsolutePath().toString(), "") - .replace(File.separator, "."); - if (rootPackageStr.startsWith(".")) { - rootPackageStr = rootPackageStr.substring(1); - } - if (rootPackageStr.endsWith(".")) { - rootPackageStr = rootPackageStr.substring(0, rootPackageStr.length() - 1); - } - result.add(rootPackageStr); - } catch (IOException e) { - log.debug("Unable to determine the sources directories", e); - // just ignore it as it's not critical for the DevUI functionality - } - } - return result; - } - - private String commonPath(List paths) { - String commonPath = ""; - List dirs = new ArrayList<>(paths.size()); - for (int i = 0; i < paths.size(); i++) { - dirs.add(i, paths.get(i).split(Pattern.quote(File.separator))); - } - for (int j = 0; j < dirs.get(0).length; j++) { - String thisDir = dirs.get(0)[j]; // grab the next directory name in the first path - boolean allMatched = true; - for (int i = 1; i < dirs.size() && allMatched; i++) { // look at the other paths - if (dirs.get(i).length < j) { //there is no directory - allMatched = false; - break; - } - allMatched = dirs.get(i)[j].equals(thisDir); //check if it matched - } - if (allMatched) { - commonPath += thisDir + File.separator; - } else { - break; - } - } - return commonPath; - } - } -} diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevTemplatePathBuildItem.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevTemplatePathBuildItem.java deleted file mode 100644 index f900b8b5c6f19..0000000000000 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevTemplatePathBuildItem.java +++ /dev/null @@ -1,58 +0,0 @@ -package io.quarkus.vertx.http.deployment.devmode.console; - -import io.quarkus.builder.item.MultiBuildItem; - -/** - * Represents a dev template path. - */ -public final class DevTemplatePathBuildItem extends MultiBuildItem { - - static final String TAGS = "tags/"; - - private final String path; - private final String contents; - - public DevTemplatePathBuildItem(String path, String contents) { - this.path = path; - this.contents = contents; - } - - /** - * Uses the {@code /} path separator. - * - * @return the path relative to the template root - */ - public String getPath() { - return path; - } - - /** - * Returns the template contents - * - * @return the template contents - */ - public String getContents() { - return contents; - } - - /** - * - * @return {@code true} if it represents a user tag, {@code false} otherwise - */ - public boolean isTag() { - return path.startsWith(TAGS); - } - - public boolean isRegular() { - return !isTag(); - } - - public String getTagName() { - int end = path.lastIndexOf('.'); - if (end == -1) { - end = path.length(); - } - return path.substring(TAGS.length(), end); - } - -} diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevTemplateVariantsBuildItem.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevTemplateVariantsBuildItem.java deleted file mode 100644 index a847c2b87334d..0000000000000 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/DevTemplateVariantsBuildItem.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.quarkus.vertx.http.deployment.devmode.console; - -import java.util.List; -import java.util.Map; - -import io.quarkus.builder.item.SimpleBuildItem; - -/** - * Holds all dev template variants found. - */ -public final class DevTemplateVariantsBuildItem extends SimpleBuildItem { - - private final Map> variants; - - public DevTemplateVariantsBuildItem(Map> variants) { - this.variants = variants; - } - - public Map> getVariants() { - return variants; - } - -} diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/FlashScopeHandler.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/FlashScopeHandler.java deleted file mode 100644 index 78bc7bc161ff7..0000000000000 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/FlashScopeHandler.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.quarkus.vertx.http.deployment.devmode.console; - -import io.quarkus.devconsole.runtime.spi.FlashScopeUtil; -import io.vertx.core.Handler; -import io.vertx.ext.web.RoutingContext; - -public class FlashScopeHandler implements Handler { - - @Override - public void handle(RoutingContext event) { - FlashScopeUtil.handleFlashCookie(event); - event.next(); - } - -} diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/JsonObjectValueResolver.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/JsonObjectValueResolver.java deleted file mode 100644 index fe4b2a01d845e..0000000000000 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/JsonObjectValueResolver.java +++ /dev/null @@ -1,48 +0,0 @@ -package io.quarkus.vertx.http.deployment.devmode.console; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; - -import io.quarkus.qute.EvalContext; -import io.quarkus.qute.Results; -import io.quarkus.qute.ValueResolver; -import io.vertx.core.json.JsonObject; - -public class JsonObjectValueResolver implements ValueResolver { - - public boolean appliesTo(EvalContext context) { - return ValueResolver.matchClass(context, JsonObject.class); - } - - @Override - public CompletionStage resolve(EvalContext context) { - JsonObject jsonObject = (JsonObject) context.getBase(); - switch (context.getName()) { - case "fieldNames": - case "fields": - return CompletableFuture.completedFuture(jsonObject.fieldNames()); - case "size": - return CompletableFuture.completedFuture(jsonObject.size()); - case "empty": - case "isEmpty": - return CompletableFuture.completedFuture(jsonObject.isEmpty()); - case "get": - if (context.getParams().size() == 1) { - return context.evaluate(context.getParams().get(0)).thenCompose(k -> { - return CompletableFuture.completedFuture(jsonObject.getValue((String) k)); - }); - } - case "containsKey": - if (context.getParams().size() == 1) { - return context.evaluate(context.getParams().get(0)).thenCompose(k -> { - return CompletableFuture.completedFuture(jsonObject.containsKey((String) k)); - }); - } - default: - return jsonObject.containsKey(context.getName()) - ? CompletableFuture.completedFuture(jsonObject.getValue(context.getName())) - : Results.notFound(context); - } - } - -} diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/MultiMapValueResolver.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/MultiMapValueResolver.java deleted file mode 100644 index 80d9444a4a805..0000000000000 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/MultiMapValueResolver.java +++ /dev/null @@ -1,53 +0,0 @@ -package io.quarkus.vertx.http.deployment.devmode.console; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; - -import io.quarkus.qute.EvalContext; -import io.quarkus.qute.Results; -import io.quarkus.qute.ValueResolver; -import io.vertx.core.MultiMap; - -public class MultiMapValueResolver implements ValueResolver { - - public boolean appliesTo(EvalContext context) { - return ValueResolver.matchClass(context, MultiMap.class); - } - - @Override - public CompletionStage resolve(EvalContext context) { - MultiMap multiMap = (MultiMap) context.getBase(); - switch (context.getName()) { - case "names": - return CompletableFuture.completedFuture(multiMap.names()); - case "size": - return CompletableFuture.completedFuture(multiMap.size()); - case "empty": - case "isEmpty": - return CompletableFuture.completedFuture(multiMap.isEmpty()); - case "get": - if (context.getParams().size() == 1) { - return context.evaluate(context.getParams().get(0)).thenCompose(k -> { - return CompletableFuture.completedFuture(multiMap.get((String) k)); - }); - } - case "getAll": - if (context.getParams().size() == 1) { - return context.evaluate(context.getParams().get(0)).thenCompose(k -> { - return CompletableFuture.completedFuture(multiMap.getAll((String) k)); - }); - } - case "contains": - if (context.getParams().size() == 1) { - return context.evaluate(context.getParams().get(0)).thenCompose(k -> { - return CompletableFuture.completedFuture(multiMap.contains((String) k)); - }); - } - default: - return multiMap.contains(context.getName()) - ? CompletableFuture.completedFuture(multiMap.get(context.getName())) - : Results.notFound(context); - } - } - -} diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/OpenIdeHandler.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/OpenIdeHandler.java deleted file mode 100644 index 7cd581886877c..0000000000000 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/OpenIdeHandler.java +++ /dev/null @@ -1,103 +0,0 @@ -package io.quarkus.vertx.http.deployment.devmode.console; - -import java.io.File; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import org.jboss.logging.Logger; - -import io.quarkus.deployment.ide.Ide; -import io.quarkus.devconsole.runtime.spi.DevConsolePostHandler; -import io.vertx.core.MultiMap; -import io.vertx.ext.web.RoutingContext; - -/** - * The purpose of this class is to open a class in the IDE on the server-side - meaning the machine - * that is running the Quarkus application itself - */ -public class OpenIdeHandler extends DevConsolePostHandler { - - private static final Logger log = Logger.getLogger(OpenIdeHandler.class); - private static final Map LANG_TO_EXT = Map.of("java", "java", "kotlin", "kt"); - - private final Ide ide; - - public OpenIdeHandler(Ide ide) { - this.ide = ide; - } - - @Override - protected void dispatch(RoutingContext routingContext, MultiMap form) { - String className = form.get("className"); - String lang = form.get("lang"); - String line = form.get("line"); - - if (isNullOrEmpty(className) || isNullOrEmpty(lang)) { - routingContext.fail(400); - } - - if (ide != null) { - typicalProcessLaunch(routingContext, className, lang, line, ide); - } else { - log.debug("Unhandled IDE : " + ide); - routingContext.fail(500); - } - } - - private void typicalProcessLaunch(RoutingContext routingContext, String className, String lang, - String line, Ide ide) { - String fileName = toFileName(className, lang); - if (fileName == null) { - routingContext.fail(404); - return; - } - List args = ide.createFileOpeningArgs(fileName, line); - launchInIDE(routingContext, ide, args); - } - - private String toFileName(String className, String lang) { - String effectiveClassName = className; - int dollarIndex = className.indexOf("$"); - if (dollarIndex > -1) { - // in this case we are dealing with inner classes, so we need to get the name of the outer class - // in order to use for conversion to the file name - effectiveClassName = className.substring(0, dollarIndex); - } - String fileName = effectiveClassName.replace('.', File.separatorChar) + "." + LANG_TO_EXT.get(lang); - Path sourceFile = Ide.findSourceFile(fileName); - if (sourceFile == null) { - return null; - } - return sourceFile.toAbsolutePath().toString(); - } - - protected void launchInIDE(RoutingContext routingContext, Ide ide, List args) { - new Thread(new Runnable() { - public void run() { - try { - String effectiveCommand = ide.getEffectiveCommand(); - if (isNullOrEmpty(effectiveCommand)) { - log.debug("Unable to determine proper launch command for IDE: " + ide); - routingContext.response().setStatusCode(500).end(); - return; - } - List command = new ArrayList<>(); - command.add(effectiveCommand); - command.addAll(args); - new ProcessBuilder(command).inheritIO().start().waitFor(10, - TimeUnit.SECONDS); - routingContext.response().setStatusCode(200).end(); - } catch (Exception e) { - routingContext.fail(e); - } - } - }, "Launch in IDE Action").start(); - } - - private boolean isNullOrEmpty(String arg) { - return arg == null || arg.isEmpty(); - } -} diff --git a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/package-info.java b/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/package-info.java deleted file mode 100644 index a7126984f6f39..0000000000000 --- a/extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/devmode/console/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * + * Package containing the dev UI v1. - * + - */ -package io.quarkus.vertx.http.deployment.devmode.console; \ No newline at end of file diff --git a/extensions/vertx-http/deployment/src/main/resources/META-INF/services/io.quarkus.dev.spi.DeploymentFailedStartHandler b/extensions/vertx-http/deployment/src/main/resources/META-INF/services/io.quarkus.dev.spi.DeploymentFailedStartHandler index 08546b42fc16c..5df142f1ac1ba 100644 --- a/extensions/vertx-http/deployment/src/main/resources/META-INF/services/io.quarkus.dev.spi.DeploymentFailedStartHandler +++ b/extensions/vertx-http/deployment/src/main/resources/META-INF/services/io.quarkus.dev.spi.DeploymentFailedStartHandler @@ -1 +1 @@ -io.quarkus.vertx.http.deployment.devmode.console.DevConsoleFailedStartHandler \ No newline at end of file +io.quarkus.vertx.http.deployment.devmode.DevModeFailedStartHandler \ No newline at end of file diff --git a/extensions/vertx-http/deployment/src/main/resources/dev-static/css/dev-console.css b/extensions/vertx-http/deployment/src/main/resources/dev-static/css/dev-console.css deleted file mode 100644 index d212884496a5a..0000000000000 --- a/extensions/vertx-http/deployment/src/main/resources/dev-static/css/dev-console.css +++ /dev/null @@ -1,107 +0,0 @@ -.quarkus-logo { - margin-right: 15px; -} - -.main-container { - margin-top: 1em; - margin-bottom: 4em; -} - -.cards-index { - padding-top: 1em; -} - -.navbar-brand { - margin-right: 0.9rem; -} - -.navbar-brand img { - border-right: 1px solid darkgrey; - padding-right: 10px; - margin-right: 5px; -} - -.navbar-text { - font-size: 0.9em; - position: absolute; - right: 5px; - bottom: 9px; -} - -.navbar-right { - font-size: 0.9em; - position: absolute; - right: 5px; - bottom: 9px; - display: inline-block; - padding-top: .5rem; - padding-bottom: .5rem; -} - -.navbar { - justify-content: unset; -} - -#navbar-title:hover { - color: #4695eb !important; -} - -#navbar-subtitle { - padding-top: 6px; - color: #4695eb; -} - -.breadcrumb-separator { - margin-right: 2px; - margin-left: 4px; -} - -.breadcrumb { - border-radius: 0px; - background-color: #f5f5f5; - border-bottom: 1px solid #ddd; - box-shadow: 0 0 6px 0px rgba(0, 0, 0, 0.2); -} - -h1 { - margin-bottom: 0.75em; -} - -.package-name { - color: dimgray; -} - -.devUiFooterButton { - color: #9a9da0; -} - -.devUiFooterButton:hover { - color: #3366ac !important; -} - -#devUiFooter { - background: #343a40; - height: 40px; -} - -#devUiFooterToolbar { - border: 1px solid #414850; - max-height: 40px; - width: 100%; - padding: unset; - position: absolute; - top: 0px; -} - -#devUiFooterResizeButton { - cursor: row-resize !important; -} - -#devUiFooter { - overflow-y: auto; - overflow-x: hidden; -} - -.guide-padding-right { - padding-right: 0.25rem; -} \ No newline at end of file diff --git a/extensions/vertx-http/deployment/src/main/resources/dev-static/images/favicon.ico b/extensions/vertx-http/deployment/src/main/resources/dev-static/images/favicon.ico deleted file mode 100644 index b4ef4208a6f48..0000000000000 Binary files a/extensions/vertx-http/deployment/src/main/resources/dev-static/images/favicon.ico and /dev/null differ diff --git a/extensions/vertx-http/deployment/src/main/resources/dev-static/images/quarkus_icon_rgb_reverse.svg b/extensions/vertx-http/deployment/src/main/resources/dev-static/images/quarkus_icon_rgb_reverse.svg deleted file mode 100644 index 1969e1e886af3..0000000000000 --- a/extensions/vertx-http/deployment/src/main/resources/dev-static/images/quarkus_icon_rgb_reverse.svg +++ /dev/null @@ -1 +0,0 @@ -quarkus_icon_rgb_1024px_reverse \ No newline at end of file diff --git a/extensions/vertx-http/deployment/src/main/resources/dev-static/js/dev-console.js b/extensions/vertx-http/deployment/src/main/resources/dev-static/js/dev-console.js deleted file mode 100644 index 0553c9d561992..0000000000000 --- a/extensions/vertx-http/deployment/src/main/resources/dev-static/js/dev-console.js +++ /dev/null @@ -1,93 +0,0 @@ - -var devUiPanelHeight; -var devUiLocalstoragekey = "quarkus_dev_ui_state"; - -$('document').ready(function () { - loadDevUiSettings(); - - devUiFooterOpenButton.addEventListener("click", openFooter); - devUiFooterCloseButton.addEventListener("click", closeFooter); - - devUiFooterResizeButton.addEventListener("mousedown", function(e){ - m_pos = e.y; - document.addEventListener("mousemove", resize, false); - }, false); - - document.addEventListener("mouseup", function(){ - document.removeEventListener("mousemove", resize, false); - saveDevUiSettings(); - }, false); - - $('[data-toggle="tooltip"]').tooltip(); - - // save settings on hide - document.addEventListener('visibilitychange', function() { - if (document.visibilityState == 'hidden') { - saveDevUiSettings(); - } - }); -}); - -function loadDevUiSettings(){ - if (devUiLocalstoragekey in localStorage) { - var state = JSON.parse(localStorage.getItem(devUiLocalstoragekey)); - - if(state.panelHeight !== null && typeof(state.panelHeight) !== 'undefined'){ - devUiPanelHeight = state.panelHeight; - openFooter(); - }else{ - closeFooter(); - devUiPanelHeight = null; - } - } -} - -function saveDevUiSettings(){ - // Running state - var state = { - "panelHeight": devUiPanelHeight - }; - - localStorage.setItem(devUiLocalstoragekey, JSON.stringify(state)); -} - -function openFooter(){ - if (devUiPanelHeight === null || devUiPanelHeight === 'undefined') { - devUiPanelHeight = "33vh"; - } - $("#devUiFooter").css("height", devUiPanelHeight); - $(".hideOnOpenFooter").hide(); - $(".showOnOpenFooter").show(); - - var element = document.getElementById("devUiFooterContent"); - element.scrollIntoView({block: "end"}); - - saveDevUiSettings(); -} - -function closeFooter(){ - devUiPanelHeight = null; - $("#devUiFooter").css("height", "40px"); - $(".hideOnOpenFooter").show(); - $(".showOnOpenFooter").hide(); - saveDevUiSettings() -} - -function resize(e){ - const dx = m_pos - e.y; - m_pos = e.y; - const panel = document.getElementById("devUiFooter"); - const content = document.getElementById("devUiFooterContent"); - - if(panel.style.height === "unset"){ - devUiPanelHeight = null; - }else{ - devUiPanelHeight = parseInt(getComputedStyle(panel, '').height) + dx; - devUiPanelHeight = "" + devUiPanelHeight; - if(!devUiPanelHeight.endsWith("vh") && !devUiPanelHeight.endsWith("px")){ - devUiPanelHeight = devUiPanelHeight + "px"; - } - panel.style.height = devUiPanelHeight; - content.style.height = devUiPanelHeight - 40; - } -} \ No newline at end of file diff --git a/extensions/vertx-http/deployment/src/main/resources/dev-templates/index.html b/extensions/vertx-http/deployment/src/main/resources/dev-templates/index.html deleted file mode 100644 index 58f57398de474..0000000000000 --- a/extensions/vertx-http/deployment/src/main/resources/dev-templates/index.html +++ /dev/null @@ -1,20 +0,0 @@ -{#include main} - {#title}Dev UI{/title} - {#body} -
-
- - {#each actionableExtensions} - {#actionableExtension it/} - {/each} -
- {#if nonActionableExtensions} -
-
- {#each nonActionableExtensions} - {#nonActionableExtension it/} - {/each} - {/if} -
- {/body} -{/include} diff --git a/extensions/vertx-http/deployment/src/main/resources/dev-templates/main.html b/extensions/vertx-http/deployment/src/main/resources/dev-templates/main.html deleted file mode 100644 index fd30d6b62da7c..0000000000000 --- a/extensions/vertx-http/deployment/src/main/resources/dev-templates/main.html +++ /dev/null @@ -1,217 +0,0 @@ - - - - - - - - - - - - - {#insert styleref /} - - - - - - - {#if currentExtensionName?? && currentExtensionName != 'Eclipse Vert.x - HTTP'} - {currentExtensionName} › - {/if} - {#insert title/} - {#if applicationName and applicationVersion} | {applicationName} {applicationVersion}{/if} - - - - - - - -
- - {#if flash.message??} - - {/if} -
- -
- - {#insert body/} -
- - - - - {#insert scriptref /} - - - - diff --git a/extensions/vertx-http/deployment/src/main/resources/dev-templates/tags/actionableExtension.html b/extensions/vertx-http/deployment/src/main/resources/dev-templates/tags/actionableExtension.html deleted file mode 100644 index abb50980659bf..0000000000000 --- a/extensions/vertx-http/deployment/src/main/resources/dev-templates/tags/actionableExtension.html +++ /dev/null @@ -1,28 +0,0 @@ -
-
-
-
-
- {it.name} -
-
- {#if it.metadata.guide??} - - {/if} -
-
-
-
-

- {#if it.metadata.status?? == 'experimental'} - EXPERIMENTAL - {/if} - {it.description??} -
- {#if it._dev??} - {it._dev.raw} - {/if} -

-
-
-
diff --git a/extensions/vertx-http/deployment/src/main/resources/dev-templates/tags/nonActionableExtension.html b/extensions/vertx-http/deployment/src/main/resources/dev-templates/tags/nonActionableExtension.html deleted file mode 100644 index 2f7543b664b6b..0000000000000 --- a/extensions/vertx-http/deployment/src/main/resources/dev-templates/tags/nonActionableExtension.html +++ /dev/null @@ -1,28 +0,0 @@ -
-
-
-
-
- {it.name} -
-
- {#if it.metadata.guide??} - - {/if} -
-
-
-
-

- {#if it.metadata.status?? == 'experimental'} - EXPERIMENTAL - {/if} - {it.description??} -
- {#if it._dev??} - {it._dev.raw} - {/if} -

-
-
-
\ No newline at end of file diff --git a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/BodyHandlerBean.java b/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/BodyHandlerBean.java deleted file mode 100644 index 016f4329c718d..0000000000000 --- a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/BodyHandlerBean.java +++ /dev/null @@ -1,42 +0,0 @@ -package io.quarkus.vertx.http.devconsole; - -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.enterprise.event.Observes; -import jakarta.inject.Inject; - -import io.quarkus.runtime.RuntimeValue; -import io.quarkus.vertx.http.runtime.HttpBuildTimeConfig; -import io.quarkus.vertx.http.runtime.HttpConfiguration; -import io.quarkus.vertx.http.runtime.VertxHttpRecorder; -import io.quarkus.vertx.http.runtime.management.ManagementInterfaceBuildTimeConfig; -import io.quarkus.vertx.http.runtime.management.ManagementInterfaceConfiguration; -import io.vertx.core.Handler; -import io.vertx.ext.web.Router; -import io.vertx.ext.web.RoutingContext; - -@ApplicationScoped -public class BodyHandlerBean { - @Inject - HttpConfiguration httpConfiguration; - @Inject - HttpBuildTimeConfig httpBuildTimeConfig; - @Inject - ManagementInterfaceConfiguration managementInterfaceConfiguration; - @Inject - ManagementInterfaceBuildTimeConfig managementInterfaceBuildTimeConfig; - - void setup(@Observes Router router) { - Handler bodyHandler = new VertxHttpRecorder(httpBuildTimeConfig, - managementInterfaceBuildTimeConfig, - new RuntimeValue<>(httpConfiguration), - new RuntimeValue<>(managementInterfaceConfiguration)) - .createBodyHandler(); - router.route().order(Integer.MIN_VALUE + 1).handler(new Handler() { - @Override - public void handle(RoutingContext routingContext) { - routingContext.request().resume(); - bodyHandler.handle(routingContext); - } - }); - } -} diff --git a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/ConfigBean.java b/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/ConfigBean.java deleted file mode 100644 index 2ebc09380fccf..0000000000000 --- a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/ConfigBean.java +++ /dev/null @@ -1,28 +0,0 @@ -package io.quarkus.vertx.http.devconsole; - -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.enterprise.event.Observes; - -import org.eclipse.microprofile.config.inject.ConfigProperty; - -import io.vertx.core.Handler; -import io.vertx.ext.web.Router; -import io.vertx.ext.web.RoutingContext; - -@ApplicationScoped -public class ConfigBean { - - @ConfigProperty(name = "message") - String message; - - void route(@Observes Router router) { - router.route("/msg").handler(new Handler() { - @Override - public void handle(RoutingContext event) { - event.response().end(message); - } - }); - - } - -} diff --git a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/DevConsoleConfigEditorBodyHandlerTest.java b/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/DevConsoleConfigEditorBodyHandlerTest.java deleted file mode 100644 index f8b2837e2f574..0000000000000 --- a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/DevConsoleConfigEditorBodyHandlerTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package io.quarkus.vertx.http.devconsole; - -import java.util.Map; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -import io.quarkus.devui.tests.DevUIJsonRPCTest; -import io.quarkus.test.QuarkusDevModeTest; -import io.restassured.RestAssured; - -/** - * This tests that the dev console still works with this extension present (i.e. with a RequireBodyHandlerBuildItem being - * produced) - *

- * The config editor is a deployment side handler, so this test that the deployment side functions of the dev console - * handle body handlers correctly. - */ -public class DevConsoleConfigEditorBodyHandlerTest extends DevUIJsonRPCTest { - - @RegisterExtension - static final QuarkusDevModeTest config = new QuarkusDevModeTest() - .withApplicationRoot((jar) -> jar.addClass(BodyHandlerBean.class)); - - public DevConsoleConfigEditorBodyHandlerTest() { - super("devui-configuration"); - } - - @Test - public void testChangeHttpRoute() throws Exception { - RestAssured.with() - .get("q/arc/beans") - .then() - .statusCode(200); - super.executeJsonRPCMethod("updateProperty", - Map.of( - "name", "quarkus.http.root-path", - "value", "/foo")); - RestAssured.with() - .get("q/arc/beans") - .then() - .statusCode(404); - RestAssured.with() - .get("foo/q/arc/beans") - .then() - .statusCode(200); - - } - -} diff --git a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/DevConsoleConfigEditorTest.java b/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/DevConsoleConfigEditorTest.java deleted file mode 100644 index 3290b3a5a8c28..0000000000000 --- a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/DevConsoleConfigEditorTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package io.quarkus.vertx.http.devconsole; - -import java.util.Map; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -import io.quarkus.devui.tests.DevUIJsonRPCTest; -import io.quarkus.test.QuarkusDevModeTest; -import io.restassured.RestAssured; - -public class DevConsoleConfigEditorTest extends DevUIJsonRPCTest { - - @RegisterExtension - static final QuarkusDevModeTest config = new QuarkusDevModeTest() - .withEmptyApplication(); - - public DevConsoleConfigEditorTest() { - super("devui-configuration"); - } - - @Test - public void testChangeHttpRoute() throws Exception { - RestAssured.with() - .get("q/arc/beans") - .then() - .statusCode(200); - super.executeJsonRPCMethod("updateProperty", - Map.of( - "name", "quarkus.http.root-path", - "value", "/foo")); - RestAssured.with() - .get("q/arc/beans") - .then() - .statusCode(404); - RestAssured.with() - .get("foo/q/arc/beans") - .then() - .statusCode(200); - - } - - @Test - public void testSetEmptyValue() throws Exception { - RestAssured.with() - .get("q/arc/beans") - .then() - .statusCode(200); - super.executeJsonRPCMethod("updateProperty", - Map.of( - "name", "quarkus.http.root-path", - "value", "")); - RestAssured.with() - .get("q/arc/beans") - .then() - .statusCode(200); - } -} diff --git a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/DevConsoleConfigMisinterpretedDoubleUnderscoreTest.java b/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/DevConsoleConfigMisinterpretedDoubleUnderscoreTest.java deleted file mode 100644 index d210591ff8bdd..0000000000000 --- a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/DevConsoleConfigMisinterpretedDoubleUnderscoreTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.quarkus.vertx.http.devconsole; - -import org.hamcrest.Matchers; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -import io.quarkus.test.QuarkusDevModeTest; -import io.restassured.RestAssured; - -/** - * Tests that a system property such as {@code %.intellij.command.histfile."} - * doesn't lead to an exception because {@code "} is incorrectly seen as a quoted property. - *

- * Originally the bug stemmed from an environment property {@code __INTELLIJ_COMMAND_HISTFILE__} - * which was (weirdly) interpreted as {@code %.intellij.command.histfile."}, - * but it's much easier to test system properties (which are mutable) - * than environment properties. - */ -public class DevConsoleConfigMisinterpretedDoubleUnderscoreTest { - - @RegisterExtension - static final QuarkusDevModeTest config = new QuarkusDevModeTest() - .setBuildSystemProperty("%.intellij.command.histfile.\"", "foo") - .withEmptyApplication(); - - @Test - public void testNoFailure() { - RestAssured.get("q/dev-ui/configuration-form-editor") - .then() - .statusCode(200).body(Matchers.containsString("loading")); - } -} diff --git a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/DevConsoleCorsTest.java b/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/DevConsoleCorsTest.java deleted file mode 100644 index fa899341ad7fe..0000000000000 --- a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/DevConsoleCorsTest.java +++ /dev/null @@ -1,194 +0,0 @@ -package io.quarkus.vertx.http.devconsole; - -import static org.hamcrest.Matchers.emptyOrNullString; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.nullValue; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -import io.quarkus.test.QuarkusDevModeTest; -import io.restassured.RestAssured; - -public class DevConsoleCorsTest { - - @RegisterExtension - static final QuarkusDevModeTest config = new QuarkusDevModeTest() - .withEmptyApplication(); - - @Test - public void testPreflightHttpLocalhostOrigin() { - String origin = "http://localhost:8080"; - String methods = "GET,POST"; - RestAssured.given() - .header("Origin", origin) - .header("Access-Control-Request-Method", methods) - .when() - .options("q/dev-ui/configuration-form-editor").then() - .statusCode(200) - .header("Access-Control-Allow-Origin", origin) - .header("Access-Control-Allow-Methods", methods) - .body(emptyOrNullString()); - } - - @Test - public void testPreflightHttpLocalhostIpOrigin() { - String origin = "http://127.0.0.1:8080"; - String methods = "GET,POST"; - RestAssured.given() - .header("Origin", origin) - .header("Access-Control-Request-Method", methods) - .when() - .options("q/dev-ui/configuration-form-editor").then() - .statusCode(200) - .header("Access-Control-Allow-Origin", origin) - .header("Access-Control-Allow-Methods", methods) - .body(emptyOrNullString()); - } - - @Test - public void testPreflightHttpsLocalhostOrigin() { - String origin = "https://localhost:8443"; - String methods = "GET,POST"; - RestAssured.given() - .header("Origin", origin) - .header("Access-Control-Request-Method", methods) - .when() - .options("q/dev-ui/configuration-form-editor").then() - .statusCode(200) - .header("Access-Control-Allow-Origin", origin) - .header("Access-Control-Allow-Methods", methods) - .body(emptyOrNullString()); - } - - @Test - public void testPreflightHttpsLocalhostIpOrigin() { - String origin = "https://127.0.0.1:8443"; - String methods = "GET,POST"; - RestAssured.given() - .header("Origin", origin) - .header("Access-Control-Request-Method", methods) - .when() - .options("q/dev-ui/configuration-form-editor").then() - .statusCode(200) - .header("Access-Control-Allow-Origin", origin) - .header("Access-Control-Allow-Methods", methods) - .body(emptyOrNullString()); - } - - @Test - public void testPreflightNonLocalhostOrigin() { - String methods = "GET,POST"; - RestAssured.given() - .header("Origin", "https://quarkus.io/http://localhost") - .header("Access-Control-Request-Method", methods) - .when() - .options("q/dev-ui/configuration-form-editor").then() - .statusCode(403) - .header("Access-Control-Allow-Origin", nullValue()) - .header("Access-Control-Allow-Methods", nullValue()) - .body(emptyOrNullString()); - } - - @Test - public void testPreflightBadLocalhostOrigin() { - String methods = "GET,POST"; - RestAssured.given() - .header("Origin", "http://localhost:8080/devui") - .header("Access-Control-Request-Method", methods) - .when() - .options("q/dev-ui/configuration-form-editor").then() - .statusCode(403) - .header("Access-Control-Allow-Origin", nullValue()) - .body(emptyOrNullString()); - } - - @Test - public void testPreflightBadLocalhostIpOrigin() { - String methods = "GET,POST"; - RestAssured.given() - .header("Origin", "http://127.0.0.1:8080/devui") - .header("Access-Control-Request-Method", methods) - .when() - .options("q/dev-ui/configuration-form-editor").then() - .statusCode(403) - .header("Access-Control-Allow-Origin", nullValue()) - .body(emptyOrNullString()); - } - - @Test - public void testPreflightLocalhostOriginWithoutPort() { - String methods = "GET,POST"; - RestAssured.given() - .header("Origin", "http://localhost") - .header("Access-Control-Request-Method", methods) - .when() - .options("q/dev-ui/configuration-form-editor").then() - .statusCode(403) - .header("Access-Control-Allow-Origin", nullValue()) - .body(emptyOrNullString()); - } - - @Test - public void testSimpleRequestHttpLocalhostOrigin() { - String origin = "http://localhost:8080"; - RestAssured.given() - .header("Origin", origin) - .when() - .get("q/dev-ui/configuration-form-editor").then() - .statusCode(200) - .header("Access-Control-Allow-Origin", origin) - .header("Access-Control-Allow-Methods", nullValue()) - .body(not(emptyOrNullString())); - } - - @Test - public void testSimpleRequestHttpLocalhostIpOrigin() { - String origin = "http://127.0.0.1:8080"; - RestAssured.given() - .header("Origin", origin) - .when() - .get("q/dev-ui/configuration-form-editor").then() - .statusCode(200) - .header("Access-Control-Allow-Origin", origin) - .header("Access-Control-Allow-Methods", nullValue()) - .body(not(emptyOrNullString())); - } - - @Test - public void testSimpleRequestHttpsLocalhostOrigin() { - String origin = "https://localhost:8443"; - RestAssured.given() - .header("Origin", origin) - .when() - .get("q/dev-ui/configuration-form-editor").then() - .statusCode(200) - .header("Access-Control-Allow-Origin", origin) - .header("Access-Control-Allow-Methods", nullValue()) - .body(not(emptyOrNullString())); - } - - @Test - public void testSimpleRequestHttpsLocalhostIpOrigin() { - String origin = "https://127.0.0.1:8443"; - RestAssured.given() - .header("Origin", origin) - .when() - .get("q/dev-ui/configuration-form-editor").then() - .statusCode(200) - .header("Access-Control-Allow-Origin", origin) - .header("Access-Control-Allow-Methods", nullValue()) - .body(not(emptyOrNullString())); - } - - @Test - public void testSimpleRequestNonLocalhostOrigin() { - RestAssured.given() - .header("Origin", "https://quarkus.io/http://localhost") - .when() - .get("q/dev-ui/configuration-form-editor").then() - .statusCode(403) - .header("Access-Control-Allow-Origin", nullValue()) - .body(emptyOrNullString()); - } -} diff --git a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/FixConfigOnErrorTest.java b/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/FixConfigOnErrorTest.java deleted file mode 100644 index a7c990fa49019..0000000000000 --- a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/FixConfigOnErrorTest.java +++ /dev/null @@ -1,40 +0,0 @@ -package io.quarkus.vertx.http.devconsole; - -import static org.hamcrest.Matchers.containsString; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -import io.quarkus.test.QuarkusDevModeTest; -import io.restassured.RestAssured; - -public class FixConfigOnErrorTest { - - @RegisterExtension - static final QuarkusDevModeTest config = new QuarkusDevModeTest() - .setAllowFailedStart(true) - .withApplicationRoot((jar) -> jar.addClass(ConfigBean.class)); - - @Test - public void testFailedStartup() { - RestAssured.with() - .get("/msg") - .then() - .statusCode(500) - .body(containsString("name=\"key.message\"")); - - RestAssured.with() - .redirects().follow(false) - .formParam("key.message", "A Message") - .formParam("redirect", "/") - .post("/io.quarkus.vertx-http.devmode.config.fix") - .then().statusCode(303); - - RestAssured.with() - .get("/msg") - .then() - .statusCode(200) - .body(containsString("A Message")); - } - -} diff --git a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/JavaDocResolverTest.java b/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/JavaDocResolverTest.java deleted file mode 100644 index 0149a9e9f50e4..0000000000000 --- a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/JavaDocResolverTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package io.quarkus.vertx.http.devconsole; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.junit.jupiter.api.Test; - -import io.quarkus.qute.Engine; -import io.quarkus.vertx.http.deployment.devmode.console.DevConsoleProcessor.JavaDocResolver; - -public class JavaDocResolverTest { - - @Test - public void testResolver() { - Engine engine = Engine.builder().addDefaults().addValueResolver(new JavaDocResolver()).build(); - assertEquals("java.lang.Foo::Class#getSimpleName()\n" - + "
@see Foo\n" - + "
@deprecated For some reason", - engine.parse("{foo.fmtJavadoc}") - .data("foo", - "{@code java.lang.Foo}::{@link Class#getSimpleName()}\n @see Foo\n @deprecated For some reason") - .render().trim()); - - } - -} diff --git a/extensions/vertx-http/dev-console-runtime-spi/src/main/java/io/quarkus/devconsole/runtime/spi/DevConsolePostHandler.java b/extensions/vertx-http/dev-console-runtime-spi/src/main/java/io/quarkus/devconsole/runtime/spi/DevConsolePostHandler.java index 67546116d7fc4..effb51d34e9cb 100644 --- a/extensions/vertx-http/dev-console-runtime-spi/src/main/java/io/quarkus/devconsole/runtime/spi/DevConsolePostHandler.java +++ b/extensions/vertx-http/dev-console-runtime-spi/src/main/java/io/quarkus/devconsole/runtime/spi/DevConsolePostHandler.java @@ -11,6 +11,10 @@ import io.vertx.core.MultiMap; import io.vertx.ext.web.RoutingContext; +/** + * @deprecated as part of the removal of the old Dev UI + */ +@Deprecated public abstract class DevConsolePostHandler implements Handler { @Override diff --git a/extensions/vertx-http/dev-console-runtime-spi/src/main/java/io/quarkus/devconsole/runtime/spi/FlashScopeUtil.java b/extensions/vertx-http/dev-console-runtime-spi/src/main/java/io/quarkus/devconsole/runtime/spi/FlashScopeUtil.java index 37bf3385e796e..4088bf2723a27 100644 --- a/extensions/vertx-http/dev-console-runtime-spi/src/main/java/io/quarkus/devconsole/runtime/spi/FlashScopeUtil.java +++ b/extensions/vertx-http/dev-console-runtime-spi/src/main/java/io/quarkus/devconsole/runtime/spi/FlashScopeUtil.java @@ -14,6 +14,10 @@ import io.vertx.core.http.Cookie; import io.vertx.ext.web.RoutingContext; +/** + * @deprecated as part of the removal of the old Dev UI + */ +@Deprecated public class FlashScopeUtil { private final static String FLASH_COOKIE_NAME = "_flash"; private final static String FLASH_CONTEXT_DATA_NAME = "flash"; diff --git a/extensions/vertx-http/dev-console-spi/src/main/java/io/quarkus/devconsole/spi/DevConsoleRouteBuildItem.java b/extensions/vertx-http/dev-console-spi/src/main/java/io/quarkus/devconsole/spi/DevConsoleRouteBuildItem.java index faf37697ff499..350d9e1a7a480 100644 --- a/extensions/vertx-http/dev-console-spi/src/main/java/io/quarkus/devconsole/spi/DevConsoleRouteBuildItem.java +++ b/extensions/vertx-http/dev-console-spi/src/main/java/io/quarkus/devconsole/spi/DevConsoleRouteBuildItem.java @@ -22,7 +22,10 @@ * {@link io.quarkus.deployment.recording.BytecodeRecorderImpl.ReturnedProxy}), *

  • in the Dev UI router (deployment class loader).
  • * + * + * @deprecated as part of the removal of the old Dev UI */ +@Deprecated public final class DevConsoleRouteBuildItem extends MultiBuildItem { public static Builder builder() { diff --git a/extensions/vertx-http/dev-console-spi/src/main/java/io/quarkus/devconsole/spi/DevConsoleRuntimeTemplateInfoBuildItem.java b/extensions/vertx-http/dev-console-spi/src/main/java/io/quarkus/devconsole/spi/DevConsoleRuntimeTemplateInfoBuildItem.java index 07b8f2fca2a28..0666dc6775052 100644 --- a/extensions/vertx-http/dev-console-spi/src/main/java/io/quarkus/devconsole/spi/DevConsoleRuntimeTemplateInfoBuildItem.java +++ b/extensions/vertx-http/dev-console-spi/src/main/java/io/quarkus/devconsole/spi/DevConsoleRuntimeTemplateInfoBuildItem.java @@ -13,7 +13,10 @@ * This is scoped to the extension that produced it, to prevent namespace clashes. * * This value will be evaluated at runtime, so can contain info that is produced from recorders + * + * @deprecated as part of the removal of the old Dev UI */ +@Deprecated public final class DevConsoleRuntimeTemplateInfoBuildItem extends MultiBuildItem { private final String groupId; diff --git a/extensions/vertx-http/dev-console-spi/src/main/java/io/quarkus/devconsole/spi/DevConsoleTemplateInfoBuildItem.java b/extensions/vertx-http/dev-console-spi/src/main/java/io/quarkus/devconsole/spi/DevConsoleTemplateInfoBuildItem.java index 69d52e55a9d41..33670db849820 100644 --- a/extensions/vertx-http/dev-console-spi/src/main/java/io/quarkus/devconsole/spi/DevConsoleTemplateInfoBuildItem.java +++ b/extensions/vertx-http/dev-console-spi/src/main/java/io/quarkus/devconsole/spi/DevConsoleTemplateInfoBuildItem.java @@ -10,7 +10,10 @@ * Information that can be directly displayed in dev console templates, using the info: prefix *

    * This is scoped to the extension that produced it, to prevent namespace clashes + * + * @deprecated as part of the removal of the old Dev UI */ +@Deprecated public final class DevConsoleTemplateInfoBuildItem extends MultiBuildItem { private final String name; diff --git a/extensions/vertx-http/dev-console-spi/src/main/java/io/quarkus/devconsole/spi/DevConsoleWebjarBuildItem.java b/extensions/vertx-http/dev-console-spi/src/main/java/io/quarkus/devconsole/spi/DevConsoleWebjarBuildItem.java index 01d16ceea3e3c..42a8bae948516 100644 --- a/extensions/vertx-http/dev-console-spi/src/main/java/io/quarkus/devconsole/spi/DevConsoleWebjarBuildItem.java +++ b/extensions/vertx-http/dev-console-spi/src/main/java/io/quarkus/devconsole/spi/DevConsoleWebjarBuildItem.java @@ -3,6 +3,10 @@ import io.quarkus.builder.item.MultiBuildItem; import io.quarkus.maven.dependency.GACT; +/** + * @deprecated as part of the removal of the old Dev UI + */ +@Deprecated public final class DevConsoleWebjarBuildItem extends MultiBuildItem { /** * ArtifactKey pointing to the web jar. Has to be one of the applications dependencies. diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/DevConsoleCORSFilter.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/devui/runtime/DevUICORSFilter.java similarity index 93% rename from extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/DevConsoleCORSFilter.java rename to extensions/vertx-http/runtime/src/main/java/io/quarkus/devui/runtime/DevUICORSFilter.java index 5deeb19c9511a..1e41984606bfd 100644 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/DevConsoleCORSFilter.java +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/devui/runtime/DevUICORSFilter.java @@ -1,4 +1,4 @@ -package io.quarkus.vertx.http.runtime.devmode; +package io.quarkus.devui.runtime; import java.time.Duration; import java.util.List; @@ -15,8 +15,8 @@ import io.vertx.core.http.HttpServerResponse; import io.vertx.ext.web.RoutingContext; -public class DevConsoleCORSFilter implements Handler { - private static final Logger LOG = Logger.getLogger(DevConsoleCORSFilter.class); +public class DevUICORSFilter implements Handler { + private static final Logger LOG = Logger.getLogger(DevUICORSFilter.class); private static final String HTTP_PORT_CONFIG_PROP = "quarkus.http.port"; private static final String HTTPS_PORT_CONFIG_PROP = "quarkus.http.ssl-port"; @@ -27,7 +27,7 @@ public class DevConsoleCORSFilter implements Handler { private static final String HTTP_LOCAL_HOST_IP = "http://" + LOCAL_HOST_IP; private static final String HTTPS_LOCAL_HOST_IP = "https://" + LOCAL_HOST_IP; - public DevConsoleCORSFilter() { + public DevUICORSFilter() { } private static CORSFilter corsFilter() { diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/ContinuousTestWebSocketHandler.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/ContinuousTestWebSocketHandler.java deleted file mode 100644 index 34f37b59bf3f6..0000000000000 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/ContinuousTestWebSocketHandler.java +++ /dev/null @@ -1,72 +0,0 @@ -package io.quarkus.vertx.http.runtime.devmode; - -import java.util.Collections; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; - -import org.jboss.logging.Logger; - -import io.netty.handler.codec.http.HttpHeaderNames; -import io.quarkus.dev.testing.ContinuousTestingSharedStateManager; -import io.vertx.core.AsyncResult; -import io.vertx.core.Handler; -import io.vertx.core.http.ServerWebSocket; -import io.vertx.ext.web.RoutingContext; - -public class ContinuousTestWebSocketHandler - implements Handler, Consumer { - - private static final Logger log = Logger.getLogger(ContinuousTestingSharedStateManager.class); - private static final Set sockets = Collections.newSetFromMap(new ConcurrentHashMap<>()); - private static volatile String lastMessage; - - @Override - public void accept(ContinuousTestingSharedStateManager.State state) { - Json.JsonObjectBuilder response = Json.object(); - response.put("running", state.running); - response.put("inProgress", state.inProgress); - response.put("run", state.run); - response.put("passed", state.passed); - response.put("failed", state.failed); - response.put("skipped", state.skipped); - response.put("isBrokenOnly", state.isBrokenOnly); - response.put("isTestOutput", state.isTestOutput); - response.put("isInstrumentationBasedReload", state.isInstrumentationBasedReload); - response.put("isLiveReload", state.isLiveReload); - - lastMessage = response.build(); - for (ServerWebSocket i : sockets) { - i.writeTextMessage(lastMessage); - } - } - - @Override - public void handle(RoutingContext event) { - - if ("websocket".equalsIgnoreCase(event.request().getHeader(HttpHeaderNames.UPGRADE))) { - event.request().toWebSocket(new Handler<>() { - @Override - public void handle(AsyncResult event) { - if (event.succeeded()) { - ServerWebSocket socket = event.result(); - if (lastMessage != null) { - socket.writeTextMessage(lastMessage); - } - sockets.add(socket); - socket.closeHandler(new Handler() { - @Override - public void handle(Void event) { - sockets.remove(socket); - } - }); - } else { - log.error("Failed to connect to test server", event.cause()); - } - } - }); - } else { - event.next(); - } - } -} diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/DevConsoleFilter.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/DevConsoleFilter.java deleted file mode 100644 index 96a321d336b49..0000000000000 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/DevConsoleFilter.java +++ /dev/null @@ -1,85 +0,0 @@ -package io.quarkus.vertx.http.runtime.devmode; - -import java.io.ByteArrayOutputStream; -import java.io.PrintWriter; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; -import java.util.concurrent.CompletableFuture; -import java.util.function.BiFunction; - -import org.jboss.logging.Logger; - -import io.netty.buffer.Unpooled; -import io.quarkus.dev.console.DevConsoleManager; -import io.quarkus.dev.console.DevConsoleRequest; -import io.quarkus.dev.console.DevConsoleResponse; -import io.vertx.core.Handler; -import io.vertx.core.buffer.Buffer; -import io.vertx.ext.web.RoutingContext; - -/** - * This is a Handler running in the regular runtime Vert.x instance - * and what it does is to take the Vert.x request coming from client (under /q/dev-v1/) - * and create the DevConsoleRequest that ends up being sent to the Netty Virtual Channel - * which is eventually piped into the Netty event loop that powers the Dev Vert.x instance. - */ -public class DevConsoleFilter implements Handler { - - private static final Logger log = Logger.getLogger(DevConsoleFilter.class); - - @Override - public void handle(RoutingContext event) { - Map> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); - for (Map.Entry entry : event.request().headers()) { - headers.put(entry.getKey(), event.request().headers().getAll(entry.getKey())); - } - if (event.getBody() != null) { - event.request().resume(); - DevConsoleRequest request = new DevConsoleRequest(event.request().method().name(), event.request().uri(), headers, - event.getBody().getBytes()); - setupFuture(event, request.getResponse()); - DevConsoleManager.sentRequest(request); - } else if (event.request().isEnded()) { - event.request().resume(); - DevConsoleRequest request = new DevConsoleRequest(event.request().method().name(), event.request().uri(), headers, - new byte[0]); - setupFuture(event, request.getResponse()); - DevConsoleManager.sentRequest(request); - } else { - event.request().bodyHandler(new Handler() { - @Override - public void handle(Buffer body) { - DevConsoleRequest request = new DevConsoleRequest(event.request().method().name(), event.request().uri(), - headers, body.getBytes()); - setupFuture(event, request.getResponse()); - DevConsoleManager.sentRequest(request); - } - }); - event.request().resume(); - } - - } - - private void setupFuture(RoutingContext event, CompletableFuture response) { - response.handle(new BiFunction() { - @Override - public Object apply(DevConsoleResponse devConsoleResponse, Throwable throwable) { - if (throwable != null) { - log.error("Failed to handle dev console request", throwable); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - throwable.printStackTrace(new PrintWriter(baos)); - event.response().setStatusCode(500).end(Buffer.buffer(baos.toByteArray())); - } else { - for (Map.Entry> entry : devConsoleResponse.getHeaders().entrySet()) { - event.response().headers().add(entry.getKey(), entry.getValue()); - } - event.response().setStatusCode(devConsoleResponse.getStatus()) - .end(Buffer.buffer(Unpooled.copiedBuffer(devConsoleResponse.getBody()))); - } - return null; - } - }); - - } -} diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/DevConsoleRecorder.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/DevConsoleRecorder.java deleted file mode 100644 index 8d89b99540370..0000000000000 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/DevConsoleRecorder.java +++ /dev/null @@ -1,87 +0,0 @@ -package io.quarkus.vertx.http.runtime.devmode; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.function.Function; -import java.util.function.Supplier; - -import org.eclipse.microprofile.config.ConfigProvider; - -import io.quarkus.dev.console.DevConsoleManager; -import io.quarkus.dev.testing.ContinuousTestingSharedStateManager; -import io.quarkus.runtime.ShutdownContext; -import io.quarkus.runtime.annotations.Recorder; -import io.smallrye.config.SmallRyeConfig; -import io.vertx.core.Handler; -import io.vertx.ext.web.RoutingContext; - -@Recorder -public class DevConsoleRecorder { - - public void addInfo(String groupId, String artifactId, String name, Supplier supplier) { - Map> info = DevConsoleManager.getTemplateInfo(); - Map data = info.computeIfAbsent(groupId + "." + artifactId, - new Function>() { - @Override - public Map apply(String s) { - return new HashMap<>(); - } - }); - data.put(name, supplier.get()); - } - - public void initConfigFun() { - SmallRyeConfig config = (SmallRyeConfig) ConfigProvider.getConfig(); - DevConsoleManager.setGlobal("devui-config-fun", new Function>() { - @Override - public Optional apply(String name) { - return config.getOptionalValue(name, String.class); - } - }); - } - - /** - * - * @param devConsoleFinalDestination - * @param shutdownContext - * @return - * @deprecated use {@link #fileSystemStaticHandler(List, ShutdownContext)} - */ - @Deprecated - public Handler devConsoleHandler(String devConsoleFinalDestination, - ShutdownContext shutdownContext) { - List webRootConfigurations = new ArrayList<>(); - webRootConfigurations.add( - new FileSystemStaticHandler.StaticWebRootConfiguration(devConsoleFinalDestination, "")); - - return fileSystemStaticHandler(webRootConfigurations, shutdownContext); - } - - public Handler fileSystemStaticHandler( - List webRootConfigurations, - ShutdownContext shutdownContext) { - - FileSystemStaticHandler fileSystemStaticHandler = new FileSystemStaticHandler(webRootConfigurations); - - shutdownContext.addShutdownTask(new ShutdownContext.CloseRunnable(fileSystemStaticHandler)); - - return fileSystemStaticHandler; - } - - public Handler continuousTestHandler(ShutdownContext context) { - - ContinuousTestWebSocketHandler handler = new ContinuousTestWebSocketHandler(); - ContinuousTestingSharedStateManager.addStateListener(handler); - context.addShutdownTask(new Runnable() { - @Override - public void run() { - ContinuousTestingSharedStateManager.removeStateListener(handler); - - } - }); - return handler; - } -} diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/RedirectHandler.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/RedirectHandler.java deleted file mode 100644 index 1bae99646484d..0000000000000 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/RedirectHandler.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.quarkus.vertx.http.runtime.devmode; - -import io.netty.handler.codec.http.HttpHeaderNames; -import io.netty.handler.codec.http.HttpResponseStatus; -import io.vertx.core.Handler; -import io.vertx.ext.web.RoutingContext; - -public class RedirectHandler implements Handler { - - @Override - public void handle(RoutingContext event) { - event.response().setStatusCode(HttpResponseStatus.TEMPORARY_REDIRECT.code()) - .putHeader(HttpHeaderNames.LOCATION, event.request().absoluteURI() + "/").end(); - } -} diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/RuntimeDevConsoleRoute.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/RuntimeDevConsoleRoute.java deleted file mode 100644 index d3adff64c5e0a..0000000000000 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/RuntimeDevConsoleRoute.java +++ /dev/null @@ -1,49 +0,0 @@ -package io.quarkus.vertx.http.runtime.devmode; - -import java.util.function.Consumer; - -import io.vertx.core.Handler; -import io.vertx.core.http.HttpMethod; -import io.vertx.ext.web.Route; -import io.vertx.ext.web.RoutingContext; - -public class RuntimeDevConsoleRoute implements Consumer { - - private String method; - - private Handler bodyHandler; - - public RuntimeDevConsoleRoute() { - } - - public RuntimeDevConsoleRoute(String method, Handler hasBodyHandler) { - this.method = method; - this.bodyHandler = hasBodyHandler; - } - - public String getMethod() { - return method; - } - - public Handler getBodyHandler() { - return bodyHandler; - } - - public void setBodyHandler(Handler bodyHandler) { - this.bodyHandler = bodyHandler; - } - - public RuntimeDevConsoleRoute setMethod(String method) { - this.method = method; - return this; - } - - @Override - public void accept(Route route) { - route.method(HttpMethod.valueOf(method)) - .order(-100); - if (bodyHandler != null) { - route.handler(bodyHandler); - } - } -}