Skip to content

Align Swagger-UI Prefix Path with Swagger-WebMvc Behavior #2862

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ public final class Constants {
/**
* The constant DEFAULT_WEB_JARS_PREFIX_URL.
*/
public static final String DEFAULT_WEB_JARS_PREFIX_URL = "/webjars";
public static final String DEFAULT_WEB_JARS_PREFIX_URL = "/webjars/swagger-ui/5.18.2";

/**
* The constant CLASSPATH_RESOURCE_LOCATION.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,10 @@
*/
package org.springdoc.webflux.core.providers;

import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springdoc.core.properties.SpringDocConfigProperties;
import org.springdoc.core.providers.SpringWebProvider;

import org.springdoc.core.utils.Constants;
import org.springframework.util.CollectionUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.reactive.result.condition.PatternsRequestCondition;
Expand All @@ -44,6 +37,13 @@
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.util.pattern.PathPattern;

import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;


/**
* The type Spring webflux provider.
Expand All @@ -66,8 +66,8 @@ public String findPathPrefix(SpringDocConfigProperties springDocConfigProperties
Set<String> patterns = getActivePatterns(requestMappingInfo);
if (!CollectionUtils.isEmpty(patterns)) {
for (String operationPath : patterns) {
if (operationPath.endsWith(springDocConfigProperties.getApiDocs().getPath()))
return operationPath.replace(springDocConfigProperties.getApiDocs().getPath(), StringUtils.EMPTY);
if (operationPath.endsWith(Constants.DEFAULT_API_DOCS_URL))
return operationPath.replace(Constants.DEFAULT_API_DOCS_URL, StringUtils.EMPTY);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@

package org.springdoc.webflux.ui;

import java.util.Optional;

import org.springdoc.core.configuration.SpringDocConfiguration;
import org.springdoc.core.properties.SpringDocConfigProperties;
import org.springdoc.core.properties.SwaggerUiConfigProperties;
Expand All @@ -36,7 +34,6 @@
import org.springdoc.core.providers.ObjectMapperProvider;
import org.springdoc.core.providers.SpringWebProvider;
import org.springdoc.webflux.core.providers.SpringWebFluxProvider;

import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType;
Expand All @@ -54,6 +51,8 @@
import org.springframework.context.annotation.Lazy;
import org.springframework.web.reactive.config.WebFluxConfigurer;

import java.util.Optional;

import static org.springdoc.core.utils.Constants.SPRINGDOC_SWAGGER_UI_ENABLED;
import static org.springdoc.core.utils.Constants.SPRINGDOC_USE_MANAGEMENT_PORT;
import static org.springdoc.core.utils.Constants.SPRINGDOC_USE_ROOT_PATH;
Expand Down Expand Up @@ -129,9 +128,9 @@ SwaggerUiHome swaggerUiHome(Optional<WebFluxProperties> optionalWebFluxPropertie
@ConditionalOnMissingBean
@Lazy(false)
SwaggerWebFluxConfigurer swaggerWebFluxConfigurer(SwaggerUiConfigProperties swaggerUiConfigProperties,
SpringDocConfigProperties springDocConfigProperties, SwaggerIndexTransformer swaggerIndexTransformer,
SpringDocConfigProperties springDocConfigProperties, SwaggerIndexTransformer swaggerIndexTransformer,
Optional<ActuatorProvider> actuatorProvider, SwaggerResourceResolver swaggerResourceResolver) {
return new SwaggerWebFluxConfigurer(swaggerUiConfigProperties,springDocConfigProperties, swaggerIndexTransformer, actuatorProvider, swaggerResourceResolver);
return new SwaggerWebFluxConfigurer(swaggerUiConfigProperties, springDocConfigProperties, swaggerIndexTransformer, actuatorProvider, swaggerResourceResolver);
}

/**
Expand Down Expand Up @@ -207,7 +206,7 @@ static class SwaggerActuatorWelcomeConfiguration {
@Lazy(false)
SwaggerWelcomeActuator swaggerActuatorWelcome(SwaggerUiConfigProperties swaggerUiConfig, SpringDocConfigProperties springDocConfigProperties,
WebEndpointProperties webEndpointProperties, ManagementServerProperties managementServerProperties) {
return new SwaggerWelcomeActuator(swaggerUiConfig, springDocConfigProperties, webEndpointProperties, managementServerProperties);
return new SwaggerWelcomeActuator(swaggerUiConfig, springDocConfigProperties, webEndpointProperties);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,22 @@
* * * *
* * *
* *
*
*
*/

package org.springdoc.webflux.ui;

import java.util.Optional;

import org.springdoc.core.properties.SpringDocConfigProperties;
import org.springdoc.core.properties.SwaggerUiConfigProperties;
import org.springdoc.core.providers.ActuatorProvider;

import org.springframework.web.reactive.config.ResourceHandlerRegistry;
import org.springframework.web.reactive.config.WebFluxConfigurer;

import java.util.Optional;

import static org.springdoc.core.utils.Constants.ALL_PATTERN;
import static org.springdoc.core.utils.Constants.CLASSPATH_RESOURCE_LOCATION;
import static org.springdoc.core.utils.Constants.DEFAULT_WEB_JARS_PREFIX_URL;
import static org.springdoc.core.utils.Constants.SWAGGER_UI_PREFIX;
import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR;

/**
Expand Down Expand Up @@ -82,8 +81,8 @@ public class SwaggerWebFluxConfigurer implements WebFluxConfigurer {
* @param swaggerResourceResolver the swagger resource resolver
*/
public SwaggerWebFluxConfigurer(SwaggerUiConfigProperties swaggerUiConfigProperties,
SpringDocConfigProperties springDocConfigProperties,
SwaggerIndexTransformer swaggerIndexTransformer,
SpringDocConfigProperties springDocConfigProperties,
SwaggerIndexTransformer swaggerIndexTransformer,
Optional<ActuatorProvider> actuatorProvider, SwaggerResourceResolver swaggerResourceResolver) {
this.swaggerIndexTransformer = swaggerIndexTransformer;
this.actuatorProvider = actuatorProvider;
Expand All @@ -100,8 +99,9 @@ public void addResourceHandlers(ResourceHandlerRegistry registry) {
uiRootPath.append(swaggerPath, 0, swaggerPath.lastIndexOf(DEFAULT_PATH_SEPARATOR));
if (actuatorProvider.isPresent() && actuatorProvider.get().isUseManagementPort())
uiRootPath.append(actuatorProvider.get().getBasePath());
registry.addResourceHandler(uiRootPath + springDocConfigProperties.getWebjars().getPrefix() + ALL_PATTERN)
.addResourceLocations(CLASSPATH_RESOURCE_LOCATION + DEFAULT_WEB_JARS_PREFIX_URL + DEFAULT_PATH_SEPARATOR)

registry.addResourceHandler(uiRootPath + SWAGGER_UI_PREFIX + ALL_PATTERN)
.addResourceLocations(CLASSPATH_RESOURCE_LOCATION + springDocConfigProperties.getWebjars().getPrefix() + DEFAULT_PATH_SEPARATOR)
.resourceChain(false)
.addResolver(swaggerResourceResolver)
.addTransformer(swaggerIndexTransformer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,20 @@

package org.springdoc.webflux.ui;

import java.util.Map;

import io.swagger.v3.oas.annotations.Operation;
import org.apache.commons.lang3.StringUtils;
import org.springdoc.core.properties.SpringDocConfigProperties;
import org.springdoc.core.properties.SwaggerUiConfigParameters;
import org.springdoc.core.properties.SwaggerUiConfigProperties;
import reactor.core.publisher.Mono;

import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties;
import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;

import java.util.Map;

import static org.springdoc.core.utils.Constants.DEFAULT_API_DOCS_ACTUATOR_URL;
import static org.springdoc.core.utils.Constants.DEFAULT_SWAGGER_UI_ACTUATOR_PATH;
Expand All @@ -68,26 +64,18 @@ public class SwaggerWelcomeActuator extends SwaggerWelcomeCommon {
*/
private final WebEndpointProperties webEndpointProperties;

/**
* The Management server properties.
*/
private final ManagementServerProperties managementServerProperties;

/**
* Instantiates a new Swagger welcome.
*
* @param swaggerUiConfig the swagger ui config
* @param springDocConfigProperties the spring doc config properties
* @param webEndpointProperties the web endpoint properties
* @param managementServerProperties the management server properties
* @param swaggerUiConfig the swagger ui config
* @param springDocConfigProperties the swagger ui config parameters
* @param webEndpointProperties the web endpoint properties
*/
public SwaggerWelcomeActuator(SwaggerUiConfigProperties swaggerUiConfig
, SpringDocConfigProperties springDocConfigProperties,
WebEndpointProperties webEndpointProperties,
ManagementServerProperties managementServerProperties) {
WebEndpointProperties webEndpointProperties) {
super(swaggerUiConfig, springDocConfigProperties);
this.webEndpointProperties = webEndpointProperties;
this.managementServerProperties = managementServerProperties;
}

/**
Expand All @@ -104,39 +92,30 @@ public Mono<Void> redirectToUi(ServerHttpRequest request, ServerHttpResponse res
return super.redirectToUi(request, response);
}


/**
* Gets swagger ui config.
* Openapi yaml map.
*
* @param request the request
* @return the swagger ui config
* @return the map
*/
@Operation(hidden = true)
@GetMapping(value = SWAGGER_CONFIG_ACTUATOR_URL, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
@Override
public Map<String, Object> getSwaggerUiConfig(ServerHttpRequest request) {
return super.getSwaggerUiConfig(request);
public Map<String, Object> openapiJson(ServerHttpRequest request) {
return super.openapiJson(request);
}

@Override
protected void calculateUiRootPath(SwaggerUiConfigParameters swaggerUiConfigParameters,StringBuilder... sbUrls) {
protected void calculateUiRootPath(SwaggerUiConfigParameters swaggerUiConfigParameters, StringBuilder... sbUrls) {
StringBuilder sbUrl = new StringBuilder();
sbUrl.append(webEndpointProperties.getBasePath());
calculateUiRootCommon(swaggerUiConfigParameters,sbUrl, sbUrls);
}

@Override
protected void calculateOauth2RedirectUrl(SwaggerUiConfigParameters swaggerUiConfigParameters, UriComponentsBuilder uriComponentsBuilder) {
if (StringUtils.isBlank(swaggerUiConfig.getOauth2RedirectUrl()) || !swaggerUiConfigParameters.isValidUrl(swaggerUiConfig.getOauth2RedirectUrl())) {
UriComponentsBuilder oauthPrefix = uriComponentsBuilder.path(managementServerProperties.getBasePath() + swaggerUiConfigParameters.getUiRootPath()).path(webJarsPrefixUrl);
swaggerUiConfigParameters.setOauth2RedirectUrl(oauthPrefix.path(getOauth2RedirectUrl()).build().toString());
}
calculateUiRootCommon(swaggerUiConfigParameters, sbUrl, sbUrls);
}

@Override
protected void buildApiDocUrl(SwaggerUiConfigParameters swaggerUiConfigParameters) {
swaggerUiConfigParameters.setApiDocsUrl( buildUrl(swaggerUiConfigParameters.getContextPath() + webEndpointProperties.getBasePath(), DEFAULT_API_DOCS_ACTUATOR_URL));
swaggerUiConfigParameters.setApiDocsUrl(buildUrl(swaggerUiConfigParameters.getContextPath() + webEndpointProperties.getBasePath(), DEFAULT_API_DOCS_ACTUATOR_URL));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,24 @@
* * * *
* * *
* *
*
*
*/

package org.springdoc.webflux.ui;

import java.net.URI;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springdoc.core.properties.SpringDocConfigProperties;
import org.springdoc.core.properties.SwaggerUiConfigParameters;
import org.springdoc.core.properties.SwaggerUiConfigProperties;
import org.springdoc.ui.AbstractSwaggerWelcome;
import reactor.core.publisher.Mono;

import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.Map;

/**
* The type Swagger welcome common.
Expand All @@ -48,11 +47,6 @@
*/
public abstract class SwaggerWelcomeCommon extends AbstractSwaggerWelcome {

/**
* The Web jars prefix url.
*/
protected String webJarsPrefixUrl;


/**
* Instantiates a new Abstract swagger welcome.
Expand All @@ -62,7 +56,6 @@ public abstract class SwaggerWelcomeCommon extends AbstractSwaggerWelcome {
*/
protected SwaggerWelcomeCommon(SwaggerUiConfigProperties swaggerUiConfig, SpringDocConfigProperties springDocConfigProperties) {
super(swaggerUiConfig, springDocConfigProperties);
this.webJarsPrefixUrl = springDocConfigProperties.getWebjars().getPrefix();
}

/**
Expand All @@ -74,14 +67,39 @@ protected SwaggerWelcomeCommon(SwaggerUiConfigProperties swaggerUiConfig, Spring
*/
protected Mono<Void> redirectToUi(ServerHttpRequest request, ServerHttpResponse response) {
SwaggerUiConfigParameters swaggerUiConfigParameters = new SwaggerUiConfigParameters(swaggerUiConfig);
this.buildFromCurrentContextPath(swaggerUiConfigParameters, request);
String sbUrl = this.buildUrl(swaggerUiConfigParameters.getContextPath(), swaggerUiConfigParameters.getUiRootPath() + springDocConfigProperties.getWebjars().getPrefix() + getSwaggerUiUrl());
buildFromCurrentContextPath(swaggerUiConfigParameters, request);
String sbUrl = swaggerUiConfigParameters.getContextPath() + swaggerUiConfigParameters.getUiRootPath() + getSwaggerUiUrl();
UriComponentsBuilder uriBuilder = getUriComponentsBuilder(swaggerUiConfigParameters, sbUrl);

// forward all queryParams from original request
request.getQueryParams().forEach(uriBuilder::queryParam);

response.setStatusCode(HttpStatus.FOUND);
response.getHeaders().setLocation(URI.create(uriBuilder.build().encode().toString()));
return response.setComplete();
}

/**
* Openapi json map.
*
* @param request the request
* @return the map
*/
protected Map<String, Object> openapiJson(ServerHttpRequest request) {
SwaggerUiConfigParameters swaggerUiConfigParameters = new SwaggerUiConfigParameters(swaggerUiConfig);
buildFromCurrentContextPath(swaggerUiConfigParameters, request);
return swaggerUiConfigParameters.getConfigParameters();
}

@Override
protected void calculateOauth2RedirectUrl(SwaggerUiConfigParameters swaggerUiConfigParameters, UriComponentsBuilder uriComponentsBuilder) {
if (StringUtils.isBlank(swaggerUiConfig.getOauth2RedirectUrl()) || !swaggerUiConfigParameters.isValidUrl(swaggerUiConfig.getOauth2RedirectUrl())) {
swaggerUiConfigParameters.setOauth2RedirectUrl(uriComponentsBuilder
.path(swaggerUiConfigParameters.getUiRootPath())
.path(getOauth2RedirectUrl()).build().toString());
}
}

/**
* Gets swagger ui config.
*
Expand All @@ -105,8 +123,13 @@ void buildFromCurrentContextPath(SwaggerUiConfigParameters swaggerUiConfigParame
super.init(swaggerUiConfigParameters);
swaggerUiConfigParameters.setContextPath(request.getPath().contextPath().value());
String url = UriComponentsBuilder.fromHttpRequest(request).toUriString();
if (!AntPathMatcher.DEFAULT_PATH_SEPARATOR.equals(request.getPath().toString()))
String target = UriComponentsBuilder.fromPath(request.getPath().contextPath().value()).toUriString();
int endIndex = url.indexOf(target) + target.length();
if (endIndex > 0) {
url = url.substring(0, endIndex);
} else {
url = url.replace(request.getPath().toString(), "");
}
buildConfigUrl(swaggerUiConfigParameters, UriComponentsBuilder.fromUriString(url));
}

Expand Down
Loading