From 5fc553fb8180c13fd81056226972ac36041e8343 Mon Sep 17 00:00:00 2001 From: altro3 Date: Thu, 19 Sep 2024 02:17:10 +0700 Subject: [PATCH] Append micronaut.server.context-path to endpoints Fixed #1774 --- .../openapi/view/OpenApiViewConfig.java | 42 +++++++++++-------- .../visitor/AbstractOpenApiVisitor.java | 4 +- .../micronaut/openapi/visitor/UrlUtils.java | 20 ++++++++- .../OpenApiControllerVisitorSpec.groovy | 38 +++++++++++++++++ 4 files changed, 83 insertions(+), 21 deletions(-) diff --git a/openapi/src/main/java/io/micronaut/openapi/view/OpenApiViewConfig.java b/openapi/src/main/java/io/micronaut/openapi/view/OpenApiViewConfig.java index 1b30a96689..8de4379868 100644 --- a/openapi/src/main/java/io/micronaut/openapi/view/OpenApiViewConfig.java +++ b/openapi/src/main/java/io/micronaut/openapi/view/OpenApiViewConfig.java @@ -21,6 +21,7 @@ import io.micronaut.core.util.CollectionUtils; import io.micronaut.core.util.StringUtils; import io.micronaut.inject.visitor.VisitorContext; +import io.micronaut.openapi.visitor.ConfigUtils; import io.micronaut.openapi.visitor.ContextUtils; import io.micronaut.openapi.visitor.Pair; import io.micronaut.openapi.visitor.group.OpenApiInfo; @@ -43,13 +44,13 @@ import java.util.Optional; import java.util.Properties; -import static io.micronaut.openapi.visitor.ConfigUtils.getConfigProperty; import static io.micronaut.openapi.visitor.ConfigUtils.getProjectPath; import static io.micronaut.openapi.visitor.ContextUtils.addGeneratedResource; import static io.micronaut.openapi.visitor.ContextUtils.info; import static io.micronaut.openapi.visitor.ContextUtils.warn; import static io.micronaut.openapi.visitor.FileUtils.readFile; import static io.micronaut.openapi.visitor.FileUtils.resolve; +import static io.micronaut.openapi.visitor.OpenApiConfigProperty.MICRONAUT_OPENAPI_CONTEXT_SERVER_PATH; import static io.micronaut.openapi.visitor.OpenApiConfigProperty.MICRONAUT_SERVER_CONTEXT_PATH; import static io.micronaut.openapi.visitor.StringUtil.COMMA; import static io.micronaut.openapi.visitor.StringUtil.DOLLAR; @@ -434,26 +435,31 @@ public String getSpecURL(AbstractViewConfig cfg, @Nullable VisitorContext contex return StringUtils.EMPTY_STRING; } - String specUrl = StringUtils.prependUri(serverContextPath, StringUtils.prependUri(mappingPath, specFile)); - if (StringUtils.isEmpty(serverContextPath)) { - String contextPath = getConfigProperty(MICRONAUT_SERVER_CONTEXT_PATH, context); - if (contextPath == null) { - contextPath = StringUtils.EMPTY_STRING; - } - if (!contextPath.startsWith(SLASH) && !contextPath.startsWith(DOLLAR)) { - contextPath = SLASH + contextPath; - } - if (!contextPath.endsWith(SLASH)) { - contextPath += SLASH; - } - if (specUrl.startsWith(SLASH)) { - specUrl = specUrl.substring(1); - } + // process micronaut.openapi.server.context.path + String serverContextPath = ConfigUtils.getConfigProperty(MICRONAUT_OPENAPI_CONTEXT_SERVER_PATH, context); + if (serverContextPath == null) { + serverContextPath = StringUtils.EMPTY_STRING; + } + String finalUrl = serverContextPath.startsWith(SLASH) ? serverContextPath : SLASH + serverContextPath; + if (!finalUrl.endsWith(SLASH)) { + finalUrl += SLASH; + } - specUrl = contextPath + specUrl; + // process micronaut.server.context-path + String contextPath = ConfigUtils.getConfigProperty(MICRONAUT_SERVER_CONTEXT_PATH, context); + if (contextPath == null) { + contextPath = StringUtils.EMPTY_STRING; + } + finalUrl += contextPath.startsWith(SLASH) ? contextPath.substring(1) : contextPath; + if (!finalUrl.endsWith(SLASH)) { + finalUrl += SLASH; } - return specUrl; + finalUrl = StringUtils.prependUri(finalUrl, StringUtils.prependUri(mappingPath, specFile)); + if (!finalUrl.startsWith(SLASH) && !finalUrl.startsWith(DOLLAR)) { + finalUrl = SLASH + finalUrl; + } + return finalUrl; } /** diff --git a/openapi/src/main/java/io/micronaut/openapi/visitor/AbstractOpenApiVisitor.java b/openapi/src/main/java/io/micronaut/openapi/visitor/AbstractOpenApiVisitor.java index 144eea1567..ea3d3540f8 100644 --- a/openapi/src/main/java/io/micronaut/openapi/visitor/AbstractOpenApiVisitor.java +++ b/openapi/src/main/java/io/micronaut/openapi/visitor/AbstractOpenApiVisitor.java @@ -124,8 +124,8 @@ Map> resolvePathItems(VisitorContext context, List>(); for (UriMatchTemplate matchTemplate : matchTemplates) { - var segms = parsePathSegments(matchTemplate.toPathString()); - var finalPaths = buildUrls(segms); + var segments = parsePathSegments(matchTemplate.toPathString()); + var finalPaths = buildUrls(segments, context); for (String finalPath : finalPaths) { List resultPathItems = resultPathItemsMap.computeIfAbsent(finalPath, k -> new ArrayList<>()); diff --git a/openapi/src/main/java/io/micronaut/openapi/visitor/UrlUtils.java b/openapi/src/main/java/io/micronaut/openapi/visitor/UrlUtils.java index ed01dd07db..25bdff9770 100644 --- a/openapi/src/main/java/io/micronaut/openapi/visitor/UrlUtils.java +++ b/openapi/src/main/java/io/micronaut/openapi/visitor/UrlUtils.java @@ -16,10 +16,13 @@ package io.micronaut.openapi.visitor; import io.micronaut.core.annotation.Internal; +import io.micronaut.core.util.StringUtils; +import io.micronaut.inject.visitor.VisitorContext; import java.util.ArrayList; import java.util.List; +import static io.micronaut.openapi.visitor.OpenApiConfigProperty.MICRONAUT_SERVER_CONTEXT_PATH; import static io.micronaut.openapi.visitor.StringUtil.CLOSE_BRACE; import static io.micronaut.openapi.visitor.StringUtil.DOLLAR; import static io.micronaut.openapi.visitor.StringUtil.OPEN_BRACE; @@ -47,7 +50,7 @@ private UrlUtils() { * @param segments url template segments * @return all possible URL variants by parsed segments. */ - public static List buildUrls(List segments) { + public static List buildUrls(List segments, VisitorContext context) { var results = new ArrayList(); @@ -57,6 +60,16 @@ public static List buildUrls(List segments) { prevSegment = segment; } + String contextPath = ConfigUtils.getConfigProperty(MICRONAUT_SERVER_CONTEXT_PATH, context); + if (StringUtils.isNotEmpty(contextPath)) { + if (!contextPath.startsWith(SLASH) && !contextPath.startsWith(DOLLAR)) { + contextPath = SLASH + contextPath; + } + if (contextPath.endsWith(SLASH)) { + contextPath = contextPath.substring(0, contextPath.length() - 1); + } + } + var resultStrings = new ArrayList(); for (var res : results) { var url = res.toString(); @@ -67,6 +80,11 @@ public static List buildUrls(List segments) { } else if (url.startsWith(SLASH + DOLLAR)) { url = url.substring(1); } + + if (StringUtils.isNotEmpty(contextPath)) { + url = contextPath + url; + } + if (!resultStrings.contains(url)) { resultStrings.add(url); } diff --git a/openapi/src/test/groovy/io/micronaut/openapi/visitor/OpenApiControllerVisitorSpec.groovy b/openapi/src/test/groovy/io/micronaut/openapi/visitor/OpenApiControllerVisitorSpec.groovy index b02ed99369..8ee8356372 100644 --- a/openapi/src/test/groovy/io/micronaut/openapi/visitor/OpenApiControllerVisitorSpec.groovy +++ b/openapi/src/test/groovy/io/micronaut/openapi/visitor/OpenApiControllerVisitorSpec.groovy @@ -8,6 +8,7 @@ import io.swagger.v3.oas.models.PathItem import io.swagger.v3.oas.models.Paths import io.swagger.v3.oas.models.media.Schema import spock.lang.Issue +import spock.util.environment.RestoreSystemProperties class OpenApiControllerVisitorSpec extends AbstractOpenApiTypeElementSpec { @@ -2459,4 +2460,41 @@ class MyBean {} operation.requestBody.content."application/json".schema operation.requestBody.content."application/json".schema.$ref == "#/components/schemas/SimpleBody" } + + @RestoreSystemProperties + void "test append micronaut.server.context-path to endpoints"() { + given: + System.setProperty(OpenApiConfigProperty.MICRONAUT_SERVER_CONTEXT_PATH, "/local-path") + System.setProperty(OpenApiConfigProperty.MICRONAUT_OPENAPI_CONTEXT_SERVER_PATH, "/server-context-path") + + buildBeanDefinition('test.MyBean', ''' +package test; + +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import jakarta.inject.Singleton; + +@Controller("/test") +class TestController { + + @Get("/save{/id}") + String save() { + return null; + } +} + +@Singleton +class MyBean {} +''') + when: + OpenAPI openAPI = Utils.testReference + def paths = openAPI.paths + + then: + paths + paths."/server-context-path/local-path/test/save" + paths."/server-context-path/local-path/test/save".get + paths."/server-context-path/local-path/test/save/{id}" + paths."/server-context-path/local-path/test/save/{id}".get + } }