Skip to content

Commit

Permalink
Add OpenAPI to management interface if enabled, with option to exclude
Browse files Browse the repository at this point in the history
Signed-off-by: Phillip Kruger <[email protected]>
  • Loading branch information
phillip-kruger committed Jul 11, 2023
1 parent ffc4731 commit 40b2157
Show file tree
Hide file tree
Showing 13 changed files with 108 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,16 @@ CardPageBuildItem createCard(NonApplicationRootPathBuildItem nonApplicationRootP
CardPageBuildItem cardPageBuildItem = new CardPageBuildItem();

// Generated GraphQL Schema
String schemaPath = "/" + graphQLConfig.rootPath + "/schema.graphql";
PageBuilder schemaPage = Page.externalPageBuilder("GraphQL Schema")
.icon("font-awesome-solid:diagram-project")
.url("/" + graphQLConfig.rootPath + "/schema.graphql");
.url(schemaPath, schemaPath);

// GraphiQL UI
String uiPath = nonApplicationRootPathBuildItem.resolvePath(graphQLConfig.ui.rootPath);
PageBuilder uiPage = Page.externalPageBuilder("GraphQL UI")
.icon("font-awesome-solid:table-columns")
.staticLabel("<a style='color: var(--lumo-contrast-80pct);' href='" + uiPath
+ "' target='_blank'><vaadin-icon class='icon' icon='font-awesome-solid:up-right-from-square'></vaadin-icon></a>")
.url(uiPath + "/index.html?embed=true");
.url(uiPath + "/index.html?embed=true", uiPath);

// Learn
PageBuilder learnLink = Page.externalPageBuilder("Learn more about GraphQL")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ public class SmallRyeHealthConfig {
@ConfigItem
Optional<String> defaultHealthGroup;

/**
* If management interface is turned on the health endpoints and ui will be published under the management interface. This
* allows you to exclude Health from management by setting the value to false
*/
@ConfigItem(name = "management.enabled", defaultValue = "true")
public boolean managementEnabled;

/**
* SmallRye Health UI configuration
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,19 @@ CardPageBuildItem create(NonApplicationRootPathBuildItem nonApplicationRootPathB
SmallRyeHealthRecorder unused) {
CardPageBuildItem pageBuildItem = new CardPageBuildItem();

var path = nonApplicationRootPathBuildItem.resolveManagementPath(config.rootPath,
managementInterfaceBuildTimeConfig, launchModeBuildItem);
String path = nonApplicationRootPathBuildItem.resolveManagementPath(config.rootPath,
managementInterfaceBuildTimeConfig, launchModeBuildItem, config.managementEnabled);

pageBuildItem.addPage(Page.externalPageBuilder("Health")
.icon("font-awesome-solid:heart-circle-bolt")
.url(path)
.url(path, path)
.isJsonContent());

String uipath = nonApplicationRootPathBuildItem.resolveManagementPath(config.ui.rootPath,
managementInterfaceBuildTimeConfig, launchModeBuildItem, config.managementEnabled);
pageBuildItem.addPage(Page.externalPageBuilder("Health UI")
.icon("font-awesome-solid:stethoscope")
.url(nonApplicationRootPathBuildItem.resolvePath(config.ui.rootPath))
.url(uipath, uipath)
.isHtmlContent());

return pageBuildItem;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ public void defineHealthRoutes(BuildProducer<RouteBuildItem> routes,

// Register the health handler
routes.produce(nonApplicationRootPathBuildItem.routeBuilder()
.management()
.management("quarkus.smallrye-health.management.enabled")
.route(healthConfig.rootPath)
.routeConfigKey("quarkus.smallrye-health.root-path")
.handler(new SmallRyeHealthHandler())
Expand All @@ -218,7 +218,7 @@ public void defineHealthRoutes(BuildProducer<RouteBuildItem> routes,

// Register the liveness handler
routes.produce(nonApplicationRootPathBuildItem.routeBuilder()
.management()
.management("quarkus.smallrye-health.management.enabled")
.nestedRoute(healthConfig.rootPath, healthConfig.livenessPath)
.handler(new SmallRyeLivenessHandler())
.displayOnNotFoundPage()
Expand All @@ -227,7 +227,7 @@ public void defineHealthRoutes(BuildProducer<RouteBuildItem> routes,

// Register the readiness handler
routes.produce(nonApplicationRootPathBuildItem.routeBuilder()
.management()
.management("quarkus.smallrye-health.management.enabled")
.nestedRoute(healthConfig.rootPath, healthConfig.readinessPath)
.handler(new SmallRyeReadinessHandler())
.displayOnNotFoundPage()
Expand All @@ -249,7 +249,7 @@ public void defineHealthRoutes(BuildProducer<RouteBuildItem> routes,

// Register the health group handlers
routes.produce(nonApplicationRootPathBuildItem.routeBuilder()
.management()
.management("quarkus.smallrye-health.management.enabled")
.nestedRoute(healthConfig.rootPath, healthConfig.groupPath)
.handler(new SmallRyeHealthGroupHandler())
.displayOnNotFoundPage()
Expand All @@ -258,7 +258,7 @@ public void defineHealthRoutes(BuildProducer<RouteBuildItem> routes,

SmallRyeIndividualHealthGroupHandler handler = new SmallRyeIndividualHealthGroupHandler();
routes.produce(nonApplicationRootPathBuildItem.routeBuilder()
.management()
.management("quarkus.smallrye-health.management.enabled")
.nestedRoute(healthConfig.rootPath, healthConfig.groupPath + "/*")
.handler(handler)
.displayOnNotFoundPage()
Expand All @@ -267,7 +267,7 @@ public void defineHealthRoutes(BuildProducer<RouteBuildItem> routes,

// Register the wellness handler
routes.produce(nonApplicationRootPathBuildItem.routeBuilder()
.management()
.management("quarkus.smallrye-health.management.enabled")
.nestedRoute(healthConfig.rootPath, healthConfig.wellnessPath)
.handler(new SmallRyeWellnessHandler())
.displayOnNotFoundPage()
Expand All @@ -276,7 +276,7 @@ public void defineHealthRoutes(BuildProducer<RouteBuildItem> routes,

// Register the startup handler
routes.produce(nonApplicationRootPathBuildItem.routeBuilder()
.management()
.management("quarkus.smallrye-health.management.enabled")
.nestedRoute(healthConfig.rootPath, healthConfig.startupPath)
.handler(new SmallRyeStartupHandler())
.displayOnNotFoundPage()
Expand Down Expand Up @@ -443,15 +443,17 @@ void registerHealthUiHandler(

Handler<RoutingContext> handler = recorder.uiHandler(result.getFinalDestination(),
healthUiPath, result.getWebRootConfigurations(), runtimeConfig, shutdownContext);
// The health ui is not a management route.

routeProducer.produce(nonApplicationRootPathBuildItem.routeBuilder()
.management("quarkus.smallrye-health.management.enabled")
.route(healthConfig.ui.rootPath)
.displayOnNotFoundPage("Health UI")
.routeConfigKey("quarkus.smallrye-health.ui.root-path")
.handler(handler)
.build());

routeProducer.produce(nonApplicationRootPathBuildItem.routeBuilder()
.management("quarkus.smallrye-health.management.enabled")
.route(healthConfig.ui.rootPath + "*")
.handler(handler)
.build());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ public final class SmallRyeOpenApiConfig {
@ConfigItem(defaultValue = "false")
public boolean ignoreStaticDocument;

/**
* If management interface is turned on the openapi schema document will be published under the management interface. This
* allows you to exclude OpenAPI from management by setting the value to false
*/
@ConfigItem(name = "management.enabled", defaultValue = "true")
public boolean managementEnabled;

/**
* A list of local directories that should be scanned for yaml and/or json files to be included in the static model.
* Example: `META-INF/openapi/`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ void handler(LaunchModeBuildItem launch,
}

routes.produce(nonApplicationRootPathBuildItem.routeBuilder()
.management("quarkus.smallrye-openapi.management.enabled")
.routeFunction(openApiConfig.path, corsFilter)
.routeConfigKey("quarkus.smallrye-openapi.path")
.handler(handler)
Expand All @@ -279,16 +280,19 @@ void handler(LaunchModeBuildItem launch,
.build());

routes.produce(nonApplicationRootPathBuildItem.routeBuilder()
.management("quarkus.smallrye-openapi.management.enabled")
.routeFunction(openApiConfig.path + ".json", corsFilter)
.handler(handler)
.build());

routes.produce(nonApplicationRootPathBuildItem.routeBuilder()
.management("quarkus.smallrye-openapi.management.enabled")
.routeFunction(openApiConfig.path + ".yaml", corsFilter)
.handler(handler)
.build());

routes.produce(nonApplicationRootPathBuildItem.routeBuilder()
.management("quarkus.smallrye-openapi.management.enabled")
.routeFunction(openApiConfig.path + ".yml", corsFilter)
.handler(handler)
.build());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,44 @@

import io.quarkus.deployment.IsDevelopment;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.LaunchModeBuildItem;
import io.quarkus.devui.spi.page.CardPageBuildItem;
import io.quarkus.devui.spi.page.Page;
import io.quarkus.smallrye.openapi.common.deployment.SmallRyeOpenApiConfig;
import io.quarkus.swaggerui.deployment.SwaggerUiConfig;
import io.quarkus.vertx.http.deployment.NonApplicationRootPathBuildItem;
import io.quarkus.vertx.http.runtime.management.ManagementInterfaceBuildTimeConfig;

public class OpenApiDevUIProcessor {

@BuildStep(onlyIf = IsDevelopment.class)
public CardPageBuildItem pages(NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem,
SwaggerUiConfig swaggerUiConfig, SmallRyeOpenApiConfig openApiConfig) {
ManagementInterfaceBuildTimeConfig managementInterfaceBuildTimeConfig,
LaunchModeBuildItem launchModeBuildItem,
SwaggerUiConfig swaggerUiConfig,
SmallRyeOpenApiConfig openApiConfig) {

String uiPath = nonApplicationRootPathBuildItem.resolvePath(swaggerUiConfig.path);
String schemaPath = nonApplicationRootPathBuildItem.resolvePath(openApiConfig.path);
String uiPath = nonApplicationRootPathBuildItem.resolveManagementPath(swaggerUiConfig.path,
managementInterfaceBuildTimeConfig, launchModeBuildItem, openApiConfig.managementEnabled);

String schemaPath = nonApplicationRootPathBuildItem.resolveManagementPath(openApiConfig.path,
managementInterfaceBuildTimeConfig, launchModeBuildItem, openApiConfig.managementEnabled);

CardPageBuildItem cardPageBuildItem = new CardPageBuildItem();

cardPageBuildItem.addPage(Page.externalPageBuilder("Schema yaml")
.url(nonApplicationRootPathBuildItem.resolvePath(schemaPath))
.url(schemaPath, schemaPath)
.isYamlContent()
.icon("font-awesome-solid:file-lines"));

String jsonSchema = schemaPath + "?format=json";
cardPageBuildItem.addPage(Page.externalPageBuilder("Schema json")
.url(nonApplicationRootPathBuildItem.resolvePath(schemaPath) + "?format=json")
.url(jsonSchema, jsonSchema)
.isJsonContent()
.icon("font-awesome-solid:file-code"));

cardPageBuildItem.addPage(Page.externalPageBuilder("Swagger UI")
.url(uiPath + "/index.html?embed=true")
.staticLabel("<a style='color: var(--lumo-contrast-80pct);' href='" + uiPath
+ "' target='_blank'><vaadin-icon class='icon' icon='font-awesome-solid:up-right-from-square'></vaadin-icon></a>")
.url(uiPath + "/index.html?embed=true", uiPath)
.isHtmlContent()
.icon("font-awesome-solid:signs-post"));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
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.management.ManagementInterfaceBuildTimeConfig;
import io.smallrye.openapi.ui.IndexHtmlCreator;
import io.smallrye.openapi.ui.Option;
import io.smallrye.openapi.ui.ThemeHref;
Expand Down Expand Up @@ -86,6 +87,7 @@ List<HotDeploymentWatchedFileBuildItem> brandingFiles() {
@BuildStep
public void getSwaggerUiFinalDestination(
NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem,
ManagementInterfaceBuildTimeConfig managementInterfaceBuildTimeConfig,
LaunchModeBuildItem launchMode,
SwaggerUiConfig swaggerUiConfig,
SmallRyeOpenApiConfig openapi,
Expand Down Expand Up @@ -119,7 +121,9 @@ public void getSwaggerUiFinalDestination(
}
}

String openApiPath = nonApplicationRootPathBuildItem.resolvePath(openapi.path);
String openApiPath = nonApplicationRootPathBuildItem.resolveManagementPath(openapi.path,
managementInterfaceBuildTimeConfig, launchMode, openapi.managementEnabled);

String swaggerUiPath = nonApplicationRootPathBuildItem.resolvePath(swaggerUiConfig.path);
ThemeHref theme = swaggerUiConfig.theme.orElse(ThemeHref.feeling_blue);

Expand Down Expand Up @@ -180,13 +184,15 @@ public void registerSwaggerUiHandler(SwaggerUiRecorder recorder,
runtimeConfig, shutdownContext);

routes.produce(nonApplicationRootPathBuildItem.routeBuilder()
.management("quarkus.smallrye-openapi.management.enabled")
.route(swaggerUiConfig.path)
.displayOnNotFoundPage("Open API UI")
.routeConfigKey("quarkus.swagger-ui.path")
.handler(handler)
.build());

routes.produce(nonApplicationRootPathBuildItem.routeBuilder()
.management("quarkus.smallrye-openapi.management.enabled")
.route(swaggerUiConfig.path + "*")
.handler(handler)
.build());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,12 @@ public Builder management() {
return this;
}

@Override
public Builder management(String managementConfigKey) {
super.management(managementConfigKey);
return this;
}

@Override
protected NotFoundPageDisplayableEndpointBuildItem getNotFoundEndpoint() {
return super.getNotFoundEndpoint();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,22 +169,27 @@ public String resolvePath(String path) {

public String resolveManagementPath(String path, ManagementInterfaceBuildTimeConfig managementInterfaceBuildTimeConfig,
LaunchModeBuildItem mode) {
return resolveManagementPath(path, managementInterfaceBuildTimeConfig, mode, true);
}

public String resolveManagementPath(String path, ManagementInterfaceBuildTimeConfig managementInterfaceBuildTimeConfig,
LaunchModeBuildItem mode, boolean extensionOverride) {
if (path == null || path.trim().isEmpty()) {
throw new IllegalArgumentException("Specified path can not be empty");
}
if (!managementInterfaceBuildTimeConfig.enabled) {
if (managementRootPath != null) {
return UriNormalizationUtil.normalizeWithBase(managementRootPath, path, false).getPath();
}
return UriNormalizationUtil.normalizeWithBase(nonApplicationRootPath, path, false).getPath();
} else {
if (managementInterfaceBuildTimeConfig.enabled && extensionOverride) {
// Best effort
String prefix = getManagementUrlPrefix(mode);
if (managementRootPath != null) {
return prefix + UriNormalizationUtil.normalizeWithBase(managementRootPath, path, false).getPath();
} else {
return prefix + path;
}
} else {
if (managementRootPath != null) {
return UriNormalizationUtil.normalizeWithBase(managementRootPath, path, false).getPath();
}
return UriNormalizationUtil.normalizeWithBase(nonApplicationRootPath, path, false).getPath();
}
}

Expand Down Expand Up @@ -411,6 +416,11 @@ public Builder management() {
return this;
}

@Override
public Builder management(String managementConfigKey) {
super.management(managementConfigKey);
return this;
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import java.util.function.Consumer;
import java.util.function.Function;

import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.ConfigProvider;

import io.quarkus.builder.item.MultiBuildItem;
import io.quarkus.vertx.http.deployment.devmode.NotFoundPageDisplayableEndpointBuildItem;
import io.quarkus.vertx.http.deployment.devmode.console.ConfiguredPathInfo;
Expand Down Expand Up @@ -210,10 +213,23 @@ public Builder routeConfigKey(String attributeName) {
}

public Builder management() {
this.isManagement = true;
return management(null);
}

public Builder management(String managementConfigKey) {
if (managementConfigKey == null || shouldInclude(managementConfigKey)) {
this.isManagement = true;
} else {
this.isManagement = false;
}
return this;
}

private boolean shouldInclude(String managementConfigKey) {
Config config = ConfigProvider.getConfig();
return config.getValue(managementConfigKey, boolean.class);
}

public RouteBuildItem build() {
if (routeFunction == null) {
throw new IllegalStateException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export class QwcExternalPage extends LitElement {
let currentPath = window.location.pathname;
currentPath = currentPath.substring(0, currentPath.indexOf('/dev'));
return html`<div class="codeBlock">
<span class="download" @click="${this._download}">
<span class="download" @click="${this._download}" title="${this._externalUrl}">
<vaadin-icon class="icon" icon="font-awesome-solid:download"></vaadin-icon>
Download
</span>
Expand Down
Loading

0 comments on commit 40b2157

Please sign in to comment.