Skip to content

Commit

Permalink
Append micronaut.server.context-path to endpoints
Browse files Browse the repository at this point in the history
Fixed #1774
  • Loading branch information
altro3 committed Sep 19, 2024
1 parent 067fd50 commit 9c46eeb
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -88,7 +89,6 @@ public final class OpenApiViewConfig {
private String mappingPath;
private String title;
private String specFile;
private String serverContextPath = StringUtils.EMPTY_STRING;
private SwaggerUIConfig swaggerUIConfig;
private RedocConfig redocConfig;
private RapidocConfig rapidocConfig;
Expand Down Expand Up @@ -390,15 +390,6 @@ private void render(AbstractViewConfig cfg, Path outputDir, String templateName,
}
}

/**
* Sets the server context path.
*
* @param contextPath The server context path.
*/
public void setServerContextPath(String contextPath) {
serverContextPath = contextPath == null ? StringUtils.EMPTY_STRING : contextPath;
}

/**
* Returns the title for the generated views.
*
Expand Down Expand Up @@ -434,26 +425,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;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ Map<String, List<PathItem>> resolvePathItems(VisitorContext context, List<UriMat
var resultPathItemsMap = new HashMap<String, List<PathItem>>();

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<PathItem> resultPathItems = resultPathItemsMap.computeIfAbsent(finalPath, k -> new ArrayList<>());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,6 @@ private void renderViews(String title, Map<Pair<String, String>, OpenApiInfo> op
if (CollectionUtils.isNotEmpty(openApiInfos)) {
cfg.setSpecFile(openApiInfos.values().iterator().next().getSpecFilePath());
}
cfg.setServerContextPath(getConfigProperty(MICRONAUT_OPENAPI_CONTEXT_SERVER_PATH, context));
cfg.render(destinationDir, context);
}
}
Expand Down
20 changes: 19 additions & 1 deletion openapi/src/main/java/io/micronaut/openapi/visitor/UrlUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -47,7 +50,7 @@ private UrlUtils() {
* @param segments url template segments
* @return all possible URL variants by parsed segments.
*/
public static List<String> buildUrls(List<Segment> segments) {
public static List<String> buildUrls(List<Segment> segments, VisitorContext context) {

var results = new ArrayList<StringBuilder>();

Expand All @@ -57,6 +60,16 @@ public static List<String> buildUrls(List<Segment> 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<String>();
for (var res : results) {
var url = res.toString();
Expand All @@ -67,6 +80,11 @@ public static List<String> buildUrls(List<Segment> 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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import spock.util.environment.RestoreSystemProperties

class OpenApiOperationViewRenderSpec extends Specification {
def cleanup() {
Expand Down Expand Up @@ -168,14 +169,15 @@ class OpenApiOperationViewRenderSpec extends Specification {
outputDir.resolve("swagger-ui").resolve("index.html").toFile().getText(StandardCharsets.UTF_8.name()).contains("link(contextPath + \"https://flattop.com/theme.css\", head, \"text/css\", \"stylesheet\")")
}

@RestoreSystemProperties
void "test render OpenApiView specification with server context path"() {
given:
System.setProperty(OpenApiConfigProperty.MICRONAUT_OPENAPI_CONTEXT_SERVER_PATH, "/context-path")
String spec = "redoc.enabled=true,rapidoc.enabled=true,swagger-ui.enabled=true,openapi-explorer.enabled=true"
OpenApiViewConfig cfg = OpenApiViewConfig.fromSpecification(spec, null, new Properties(), null)
Path outputDir = Paths.get("output")
cfg.title = "OpenAPI documentation"
cfg.specFile = "swagger.yml"
cfg.serverContextPath = "/context-path"
cfg.render(outputDir, null)

expect:
Expand Down Expand Up @@ -233,14 +235,15 @@ class OpenApiOperationViewRenderSpec extends Specification {
outputDir.resolve("openapi-explorer").resolve("index.html").toFile().getText(StandardCharsets.UTF_8.name()).contains(cfg.getSpecURL(cfg.openApiExplorerConfig, null))
}

@RestoreSystemProperties
void "test render OpenApiView specification with custom mapping path and server context path"() {
given:
System.setProperty(OpenApiConfigProperty.MICRONAUT_OPENAPI_CONTEXT_SERVER_PATH, "/context-path")
String spec = "mapping.path=somewhere,redoc.enabled=true,rapidoc.enabled=true,swagger-ui.enabled=true,openapi-explorer.enabled=true"
OpenApiViewConfig cfg = OpenApiViewConfig.fromSpecification(spec, null, new Properties(), null)
Path outputDir = Paths.get("output")
cfg.title = "OpenAPI documentation"
cfg.specFile = "swagger.yml"
cfg.serverContextPath = "/context-path"
cfg.render(outputDir, null)

expect:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -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
}
}

0 comments on commit 9c46eeb

Please sign in to comment.