diff --git a/pom.xml b/pom.xml index 79b1e9be8..f4e01901b 100644 --- a/pom.xml +++ b/pom.xml @@ -70,8 +70,6 @@ 2.2.9 4.18.1 2.5.2.RELEASE - 4.8.149 - 0.52 1.8.1 2.1 1.1 @@ -96,17 +94,6 @@ swagger-ui ${swagger-ui.version} - - org.webjars - webjars-locator-core - ${webjars-locator-core.version} - - - io.github.classgraph - classgraph - - - org.springframework.security.oauth spring-security-oauth2 @@ -117,11 +104,6 @@ spring-security-oauth2-authorization-server ${spring-security-oauth2-authorization-server.version} - - io.github.classgraph - classgraph - ${classgraph.version} - javax.xml jaxb-impl diff --git a/springdoc-openapi-common/pom.xml b/springdoc-openapi-common/pom.xml index 927392ca1..a2ea6447e 100644 --- a/springdoc-openapi-common/pom.xml +++ b/springdoc-openapi-common/pom.xml @@ -44,6 +44,12 @@ + + + src/main/resources + true + + org.apache.maven.plugins diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocUIConfiguration.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocUIConfiguration.java new file mode 100644 index 000000000..dc0b0e398 --- /dev/null +++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocUIConfiguration.java @@ -0,0 +1,95 @@ +/* + * + * * + * * * + * * * * + * * * * * Copyright 2019-2022 the original author or authors. + * * * * * + * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * you may not use this file except in compliance with the License. + * * * * * You may obtain a copy of the License at + * * * * * + * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * + * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * See the License for the specific language governing permissions and + * * * * * limitations under the License. + * * * * + * * * + * * + * + */ + +package org.springdoc.core; + +import java.io.IOException; +import java.util.Optional; +import java.util.Properties; + +import org.apache.commons.lang3.StringUtils; + +import org.springframework.beans.factory.InitializingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PropertiesLoaderUtils; +import org.springframework.util.AntPathMatcher; + +/** + * The type Spring doc Native Configuration. + * @author bnasslahsen + */ +@Lazy(false) +@ConditionalOnExpression("${springdoc.api-docs.enabled:true}") +@ConditionalOnWebApplication +@Configuration(proxyBeanMethods = false) +@ConditionalOnBean(SpringDocConfiguration.class) +public class SpringDocUIConfiguration implements InitializingBean { + + /** + * The constant SPRINGDOC_CONFIG_PROPERTIES. + */ + public static final String SPRINGDOC_CONFIG_PROPERTIES = "springdoc.config.properties"; + + /** + * The constant SPRINGDOC_SWAGGERUI_VERSION. + */ + private static final String SPRINGDOC_SWAGGER_UI_VERSION = "springdoc.swagger-ui.version"; + + /** + * The Swagger ui config properties. + */ + private final Optional optionalSwaggerUiConfigProperties; + + /** + * Instantiates a new Spring doc hints. + * + * @param optionalSwaggerUiConfigProperties the swagger ui config properties + */ + public SpringDocUIConfiguration(Optional optionalSwaggerUiConfigProperties) { + this.optionalSwaggerUiConfigProperties = optionalSwaggerUiConfigProperties; + } + + @Override + public void afterPropertiesSet() { + optionalSwaggerUiConfigProperties.ifPresent(swaggerUiConfigProperties -> { + if (StringUtils.isEmpty(swaggerUiConfigProperties.getVersion())) { + try { + Resource resource = new ClassPathResource(AntPathMatcher.DEFAULT_PATH_SEPARATOR + SPRINGDOC_CONFIG_PROPERTIES); + Properties props = PropertiesLoaderUtils.loadProperties(resource); + swaggerUiConfigProperties.setVersion(props.getProperty(SPRINGDOC_SWAGGER_UI_VERSION)); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + }); + } +} + diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/ui/AbstractSwaggerResourceResolver.java b/springdoc-openapi-common/src/main/java/org/springdoc/ui/AbstractSwaggerResourceResolver.java new file mode 100644 index 000000000..2c27d3e9e --- /dev/null +++ b/springdoc-openapi-common/src/main/java/org/springdoc/ui/AbstractSwaggerResourceResolver.java @@ -0,0 +1,75 @@ +package org.springdoc.ui; + +import java.io.File; + +import org.springdoc.core.SwaggerUiConfigProperties; + +import org.springframework.lang.Nullable; + +/** + * The type Web jars version resource resolver. + * + * @author bnasslahsen + */ +public class AbstractSwaggerResourceResolver { + + /** + * The Swagger ui config properties. + */ + private final SwaggerUiConfigProperties swaggerUiConfigProperties; + + /** + * Instantiates a new Web jars version resource resolver. + * + * @param swaggerUiConfigProperties the swagger ui config properties + */ + public AbstractSwaggerResourceResolver(SwaggerUiConfigProperties swaggerUiConfigProperties) { + this.swaggerUiConfigProperties = swaggerUiConfigProperties; + } + + /** + * Find web jar resource path string. + * + * @param path the path + * @return the string + */ + @Nullable + protected String findWebJarResourcePath(String path) { + String webjar = webjar(path); + if (webjar.length() > 0) { + String version = swaggerUiConfigProperties.getVersion(); + if (version != null) { + String partialPath = path(webjar, path); + return webjar + File.separator + version + File.separator + partialPath; + } + } + return null; + } + + /** + * Webjar string. + * + * @param path the path + * @return the string + */ + private String webjar(String path) { + int startOffset = (path.startsWith("/") ? 1 : 0); + int endOffset = path.indexOf('/', 1); + return endOffset != -1 ? path.substring(startOffset, endOffset) : path; + } + + + /** + * Path string. + * + * @param webjar the webjar + * @param path the path + * @return the string + */ + private String path(String webjar, String path) { + if (path.startsWith(webjar)) { + path = path.substring(webjar.length() + 1); + } + return path; + } +} \ No newline at end of file diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/ui/AbstractSwaggerWelcome.java b/springdoc-openapi-common/src/main/java/org/springdoc/ui/AbstractSwaggerWelcome.java index d3f523876..a95739c92 100644 --- a/springdoc-openapi-common/src/main/java/org/springdoc/ui/AbstractSwaggerWelcome.java +++ b/springdoc-openapi-common/src/main/java/org/springdoc/ui/AbstractSwaggerWelcome.java @@ -31,16 +31,14 @@ import org.springframework.util.CollectionUtils; import org.springframework.web.util.UriComponentsBuilder; -import static org.springdoc.core.Constants.INDEX_PAGE; -import static org.springdoc.core.Constants.OAUTH_REDIRECT_PAGE; import static org.springdoc.core.Constants.SWAGGER_UI_OAUTH_REDIRECT_URL; -import static org.springdoc.core.Constants.SWAGGER_UI_PREFIX; import static org.springdoc.core.Constants.SWAGGER_UI_URL; import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR; /** * The type Abstract swagger welcome. + * * @author bnasslashen */ public abstract class AbstractSwaggerWelcome { @@ -222,12 +220,7 @@ protected void calculateUiRootCommon(StringBuilder sbUrl, StringBuilder[] sbUrls * @return the oauth2 redirect url */ protected String getOauth2RedirectUrl() { - if (StringUtils.isNotEmpty(swaggerUiConfig.getVersion())) { - return StringUtils.defaultIfBlank(swaggerUiConfig.getOauth2RedirectUrl(), SWAGGER_UI_PREFIX + DEFAULT_PATH_SEPARATOR + swaggerUiConfig.getVersion() + OAUTH_REDIRECT_PAGE); - } - else { - return StringUtils.defaultIfBlank(swaggerUiConfig.getOauth2RedirectUrl(), SWAGGER_UI_OAUTH_REDIRECT_URL); - } + return StringUtils.defaultIfBlank(swaggerUiConfig.getOauth2RedirectUrl(), SWAGGER_UI_OAUTH_REDIRECT_URL); } /** @@ -236,9 +229,6 @@ protected String getOauth2RedirectUrl() { * @return the swagger ui url */ protected String getSwaggerUiUrl() { - if (StringUtils.isNotEmpty(swaggerUiConfig.getVersion())) - return SWAGGER_UI_PREFIX + DEFAULT_PATH_SEPARATOR + swaggerUiConfig.getVersion() + INDEX_PAGE; - else - return SWAGGER_UI_URL; + return SWAGGER_UI_URL; } } \ No newline at end of file diff --git a/springdoc-openapi-common/src/main/resources/springdoc.config.properties b/springdoc-openapi-common/src/main/resources/springdoc.config.properties new file mode 100644 index 000000000..ccf07a7fe --- /dev/null +++ b/springdoc-openapi-common/src/main/resources/springdoc.config.properties @@ -0,0 +1 @@ +springdoc.swagger-ui.version=@swagger-ui.version@ \ No newline at end of file diff --git a/springdoc-openapi-ui/pom.xml b/springdoc-openapi-ui/pom.xml index 2cb77ee6f..66d29004e 100644 --- a/springdoc-openapi-ui/pom.xml +++ b/springdoc-openapi-ui/pom.xml @@ -23,14 +23,6 @@ org.webjars swagger-ui - - org.webjars - webjars-locator-core - - - io.github.classgraph - classgraph - org.springframework.boot spring-boot-starter-security diff --git a/springdoc-openapi-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerConfig.java b/springdoc-openapi-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerConfig.java index e580d6101..b99be8fb3 100644 --- a/springdoc-openapi-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerConfig.java +++ b/springdoc-openapi-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerConfig.java @@ -55,6 +55,7 @@ /** * The type Swagger config. + * * @author bnasslahsen */ @Lazy(false) @@ -149,8 +150,9 @@ SwaggerIndexTransformer indexPageTransformer(SwaggerUiConfigProperties swaggerUi @Bean @ConditionalOnMissingBean @Lazy(false) - SwaggerWebMvcConfigurer swaggerWebMvcConfigurer(SwaggerUiConfigParameters swaggerUiConfigParameters, SwaggerIndexTransformer swaggerIndexTransformer, Optional actuatorProvider) { - return new SwaggerWebMvcConfigurer(swaggerUiConfigParameters, swaggerIndexTransformer, actuatorProvider); + SwaggerWebMvcConfigurer swaggerWebMvcConfigurer(SwaggerUiConfigParameters swaggerUiConfigParameters, SwaggerIndexTransformer swaggerIndexTransformer, + Optional actuatorProvider, SwaggerResourceResolver swaggerResourceResolver) { + return new SwaggerWebMvcConfigurer(swaggerUiConfigParameters, swaggerIndexTransformer, actuatorProvider, swaggerResourceResolver); } /** @@ -166,6 +168,12 @@ SwaggerUiConfigParameters swaggerUiConfigParameters(SwaggerUiConfigProperties sw return new SwaggerUiConfigParameters(swaggerUiConfig); } + @Bean + @ConditionalOnMissingBean + @Lazy(false) + SwaggerResourceResolver swaggerResourceResolver(SwaggerUiConfigProperties swaggerUiConfigProperties) { + return new SwaggerResourceResolver(swaggerUiConfigProperties); + } /** * The type Swagger actuator welcome configuration. */ @@ -190,4 +198,5 @@ SwaggerWelcomeActuator swaggerActuatorWelcome(SwaggerUiConfigProperties swaggerU return new SwaggerWelcomeActuator(swaggerUiConfig, springDocConfigProperties, swaggerUiConfigParameters, webEndpointProperties); } } + } diff --git a/springdoc-openapi-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerResourceResolver.java b/springdoc-openapi-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerResourceResolver.java new file mode 100644 index 000000000..1f5098a7e --- /dev/null +++ b/springdoc-openapi-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerResourceResolver.java @@ -0,0 +1,50 @@ +package org.springdoc.webmvc.ui; + +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +import org.springdoc.core.SwaggerUiConfigProperties; +import org.springdoc.ui.AbstractSwaggerResourceResolver; + +import org.springframework.core.io.Resource; +import org.springframework.web.servlet.resource.ResourceResolver; +import org.springframework.web.servlet.resource.ResourceResolverChain; + +/** + * The type Web jars version resource resolver. + * + * @author bnasslahsen + */ +public class SwaggerResourceResolver extends AbstractSwaggerResourceResolver implements ResourceResolver { + + /** + * Instantiates a new Web jars version resource resolver. + * + * @param swaggerUiConfigProperties the swagger ui config properties + */ + public SwaggerResourceResolver(SwaggerUiConfigProperties swaggerUiConfigProperties) { + super(swaggerUiConfigProperties); + } + + @Override + public Resource resolveResource(HttpServletRequest request, String requestPath, List locations, ResourceResolverChain chain) { + Resource resolved = chain.resolveResource(request, requestPath, locations); + if (resolved == null) { + String webJarResourcePath = findWebJarResourcePath(requestPath); + if (webJarResourcePath != null) + return chain.resolveResource(request, webJarResourcePath, locations); + } + return resolved; } + + @Override + public String resolveUrlPath(String resourcePath, List locations, ResourceResolverChain chain) { + String path = chain.resolveUrlPath(resourcePath, locations); + if (path == null) { + String webJarResourcePath = findWebJarResourcePath(resourcePath); + if (webJarResourcePath != null) + return chain.resolveUrlPath(webJarResourcePath, locations); + } + return path; + } +} \ No newline at end of file diff --git a/springdoc-openapi-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerWebMvcConfigurer.java b/springdoc-openapi-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerWebMvcConfigurer.java index 998bc904e..6d269be61 100644 --- a/springdoc-openapi-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerWebMvcConfigurer.java +++ b/springdoc-openapi-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerWebMvcConfigurer.java @@ -74,19 +74,26 @@ public class SwaggerWebMvcConfigurer implements WebMvcConfigurer { */ private final Optional actuatorProvider; + /** + * The Swagger resource resolver. + */ + private final SwaggerResourceResolver swaggerResourceResolver; + /** * Instantiates a new Swagger web mvc configurer. * * @param swaggerUiConfigParameters the swagger ui calculated config * @param swaggerIndexTransformer the swagger index transformer * @param actuatorProvider the actuator provider + * @param swaggerResourceResolver the swagger resource resolver */ public SwaggerWebMvcConfigurer(SwaggerUiConfigParameters swaggerUiConfigParameters, SwaggerIndexTransformer swaggerIndexTransformer, - Optional actuatorProvider) { + Optional actuatorProvider, SwaggerResourceResolver swaggerResourceResolver) { this.swaggerPath = swaggerUiConfigParameters.getPath(); this.swaggerIndexTransformer = swaggerIndexTransformer; this.actuatorProvider = actuatorProvider; + this.swaggerResourceResolver = swaggerResourceResolver; } @Override @@ -101,11 +108,13 @@ public void addResourceHandlers(ResourceHandlerRegistry registry) { .addResourceLocations(CLASSPATH_RESOURCE_LOCATION + DEFAULT_WEB_JARS_PREFIX_URL + DEFAULT_PATH_SEPARATOR) .setCachePeriod(0) .resourceChain(false) + .addResolver(swaggerResourceResolver) .addTransformer(swaggerIndexTransformer); registry.addResourceHandler(uiRootPath + SWAGGER_UI_PREFIX + "*/**") .addResourceLocations(CLASSPATH_RESOURCE_LOCATION + DEFAULT_WEB_JARS_PREFIX_URL + DEFAULT_PATH_SEPARATOR) .resourceChain(false) + .addResolver(swaggerResourceResolver) .addTransformer(swaggerIndexTransformer); } diff --git a/springdoc-openapi-ui/src/main/resources/META-INF/spring.factories b/springdoc-openapi-ui/src/main/resources/META-INF/spring.factories index fef805096..0ddf2a7ba 100644 --- a/springdoc-openapi-ui/src/main/resources/META-INF/spring.factories +++ b/springdoc-openapi-ui/src/main/resources/META-INF/spring.factories @@ -2,4 +2,5 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springdoc.webmvc.ui.SwaggerConfig,\ org.springdoc.core.SwaggerUiConfigProperties,\ org.springdoc.core.SwaggerUiConfigParameters,\ +org.springdoc.core.SpringDocUIConfiguration,\ org.springdoc.core.SwaggerUiOAuthProperties \ No newline at end of file diff --git a/springdoc-openapi-ui/src/test/java/test/org/springdoc/ui/app20/HelloController.java b/springdoc-openapi-ui/src/test/java/test/org/springdoc/ui/app20/HelloController.java deleted file mode 100644 index bf6a6803c..000000000 --- a/springdoc-openapi-ui/src/test/java/test/org/springdoc/ui/app20/HelloController.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * - * * Copyright 2019-2020 the original author or authors. - * * - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * https://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * - */ - -package test.org.springdoc.ui.app20; - -import javax.validation.Valid; -import javax.validation.constraints.Size; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class HelloController { - - @GetMapping(value = "/persons") - public void persons(@Valid @RequestParam @Size(min = 4, max = 6) String name) { - - } - -} diff --git a/springdoc-openapi-ui/src/test/java/test/org/springdoc/ui/app20/SpringDocApp20Test.java b/springdoc-openapi-ui/src/test/java/test/org/springdoc/ui/app20/SpringDocApp20Test.java deleted file mode 100644 index 5d3c0dfe3..000000000 --- a/springdoc-openapi-ui/src/test/java/test/org/springdoc/ui/app20/SpringDocApp20Test.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * * Copyright 2019-2020 the original author or authors. - * * - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * https://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * - */ - -package test.org.springdoc.ui.app20; - -import org.junit.jupiter.api.Test; -import org.springdoc.core.SwaggerUiConfigProperties; -import test.org.springdoc.ui.AbstractSpringDocTest; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.test.context.TestPropertySource; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -@TestPropertySource(properties = "springdoc.swagger-ui.version=4.1.0") -public class SpringDocApp20Test extends AbstractSpringDocTest { - - @Autowired - private SwaggerUiConfigProperties swaggerUiConfig; - - - @Test - public void testAddSwaggerUiVersionToPath() throws Exception { - mockMvc.perform(get("/swagger-ui.html")) - .andExpect(status().isFound()) - .andExpect(header().string("Location", "/swagger-ui/" + swaggerUiConfig.getVersion() + "/index.html")); - } - - - @SpringBootApplication - static class SpringDocTestApp { - } - -} \ No newline at end of file diff --git a/springdoc-openapi-webflux-core/src/test/java/test/org/springdoc/api/app145/SpringDocApp1452Test.java b/springdoc-openapi-webflux-core/src/test/java/test/org/springdoc/api/app145/SpringDocApp1452Test.java index f64973103..b838c06d7 100644 --- a/springdoc-openapi-webflux-core/src/test/java/test/org/springdoc/api/app145/SpringDocApp1452Test.java +++ b/springdoc-openapi-webflux-core/src/test/java/test/org/springdoc/api/app145/SpringDocApp1452Test.java @@ -36,7 +36,7 @@ "springdoc.use-management-port=true", "springdoc.group-configs[0].group=users", "springdoc.group-configs[0].packages-to-scan=test.org.springdoc.api.app145", - "management.server.port=9096", + "management.server.port=9066", "management.endpoints.web.base-path=/application" }) public class SpringDocApp1452Test extends AbstractSpringDocActuatorTest { diff --git a/springdoc-openapi-webflux-ui/pom.xml b/springdoc-openapi-webflux-ui/pom.xml index b66ef0994..e3b16ea75 100644 --- a/springdoc-openapi-webflux-ui/pom.xml +++ b/springdoc-openapi-webflux-ui/pom.xml @@ -18,14 +18,6 @@ org.webjars swagger-ui - - org.webjars - webjars-locator-core - - - io.github.classgraph - classgraph - org.springframework.boot diff --git a/springdoc-openapi-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerConfig.java b/springdoc-openapi-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerConfig.java index bd1a2af0e..f551a3e03 100644 --- a/springdoc-openapi-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerConfig.java +++ b/springdoc-openapi-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerConfig.java @@ -119,13 +119,16 @@ SwaggerUiHome swaggerUiHome(Optional optionalWebFluxPropertie * @param springDocConfigProperties the spring doc config properties * @param swaggerIndexTransformer the swagger index transformer * @param actuatorProvider the actuator provider + * @param swaggerResourceResolver the swagger resource resolver * @return the swagger web flux configurer */ @Bean @ConditionalOnMissingBean @Lazy(false) - SwaggerWebFluxConfigurer swaggerWebFluxConfigurer(SwaggerUiConfigParameters swaggerUiConfigParameters, SpringDocConfigProperties springDocConfigProperties, SwaggerIndexTransformer swaggerIndexTransformer, Optional actuatorProvider) { - return new SwaggerWebFluxConfigurer(swaggerUiConfigParameters, springDocConfigProperties, swaggerIndexTransformer, actuatorProvider); + SwaggerWebFluxConfigurer swaggerWebFluxConfigurer(SwaggerUiConfigParameters swaggerUiConfigParameters, + SpringDocConfigProperties springDocConfigProperties, SwaggerIndexTransformer swaggerIndexTransformer, + Optional actuatorProvider, SwaggerResourceResolver swaggerResourceResolver) { + return new SwaggerWebFluxConfigurer(swaggerUiConfigParameters, springDocConfigProperties, swaggerIndexTransformer, actuatorProvider, swaggerResourceResolver); } /** @@ -171,6 +174,19 @@ SpringWebProvider springWebProvider() { return new SpringWebFluxProvider(); } + /** + * Swagger resource resolver swagger resource resolver. + * + * @param swaggerUiConfigProperties the swagger ui config properties + * @return the swagger resource resolver + */ + @Bean + @ConditionalOnMissingBean + @Lazy(false) + SwaggerResourceResolver swaggerResourceResolver(SwaggerUiConfigProperties swaggerUiConfigProperties) { + return new SwaggerResourceResolver(swaggerUiConfigProperties); + } + /** * The type Swagger actuator welcome configuration. * @author bnasslashen diff --git a/springdoc-openapi-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerResourceResolver.java b/springdoc-openapi-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerResourceResolver.java new file mode 100644 index 000000000..ce16faaf2 --- /dev/null +++ b/springdoc-openapi-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerResourceResolver.java @@ -0,0 +1,54 @@ +package org.springdoc.webflux.ui; + +import java.io.File; +import java.util.List; + +import org.springdoc.core.SwaggerUiConfigProperties; +import org.springdoc.ui.AbstractSwaggerResourceResolver; +import reactor.core.publisher.Mono; + +import org.springframework.core.io.Resource; +import org.springframework.lang.Nullable; +import org.springframework.web.reactive.resource.ResourceResolver; +import org.springframework.web.reactive.resource.ResourceResolverChain; +import org.springframework.web.server.ServerWebExchange; + +/** + * The type Web jars version resource resolver. + * + * @author bnasslahsen + */ +public class SwaggerResourceResolver extends AbstractSwaggerResourceResolver implements ResourceResolver { + + + /** + * Instantiates a new Web jars version resource resolver. + * + * @param swaggerUiConfigProperties the swagger ui config properties + */ + public SwaggerResourceResolver(SwaggerUiConfigProperties swaggerUiConfigProperties) { + super(swaggerUiConfigProperties); + } + + @Override + public Mono resolveResource(ServerWebExchange exchange, String requestPath, List locations, ResourceResolverChain chain) { + Mono resolved = chain.resolveResource(exchange, requestPath, locations); + if (!Mono.empty().equals(resolved)) { + String webJarResourcePath = findWebJarResourcePath(requestPath); + if (webJarResourcePath != null) + return chain.resolveResource(exchange, webJarResourcePath, locations); + } + return resolved; + } + + @Override + public Mono resolveUrlPath(String resourcePath, List locations, ResourceResolverChain chain) { + Mono path = chain.resolveUrlPath(resourcePath, locations); + if (!Mono.empty().equals(path)) { + String webJarResourcePath = findWebJarResourcePath(resourcePath); + if (webJarResourcePath != null) + return chain.resolveUrlPath(webJarResourcePath, locations); + } + return path; + } +} \ No newline at end of file diff --git a/springdoc-openapi-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerWebFluxConfigurer.java b/springdoc-openapi-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerWebFluxConfigurer.java index fc6cda4b4..f762b0038 100644 --- a/springdoc-openapi-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerWebFluxConfigurer.java +++ b/springdoc-openapi-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerWebFluxConfigurer.java @@ -62,6 +62,11 @@ public class SwaggerWebFluxConfigurer implements WebFluxConfigurer { */ private final Optional actuatorProvider; + /** + * The Swagger resource resolver. + */ + private final SwaggerResourceResolver swaggerResourceResolver; + /** * Instantiates a new Swagger web flux configurer. * @@ -69,15 +74,17 @@ public class SwaggerWebFluxConfigurer implements WebFluxConfigurer { * @param springDocConfigProperties the spring doc config properties * @param swaggerIndexTransformer the swagger index transformer * @param actuatorProvider the actuator provider + * @param swaggerResourceResolver the swagger resource resolver */ public SwaggerWebFluxConfigurer(SwaggerUiConfigParameters swaggerUiConfigParameters, SpringDocConfigProperties springDocConfigProperties, SwaggerIndexTransformer swaggerIndexTransformer, - Optional actuatorProvider) { + Optional actuatorProvider, SwaggerResourceResolver swaggerResourceResolver) { this.swaggerPath = swaggerUiConfigParameters.getPath(); this.webJarsPrefixUrl = springDocConfigProperties.getWebjars().getPrefix(); this.swaggerIndexTransformer = swaggerIndexTransformer; this.actuatorProvider = actuatorProvider; + this.swaggerResourceResolver = swaggerResourceResolver; } @Override @@ -90,6 +97,7 @@ public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(uiRootPath + webJarsPrefixUrl + ALL_PATTERN) .addResourceLocations(CLASSPATH_RESOURCE_LOCATION + DEFAULT_WEB_JARS_PREFIX_URL + DEFAULT_PATH_SEPARATOR) .resourceChain(false) + .addResolver(swaggerResourceResolver) .addTransformer(swaggerIndexTransformer); } diff --git a/springdoc-openapi-webflux-ui/src/main/resources/META-INF/spring.factories b/springdoc-openapi-webflux-ui/src/main/resources/META-INF/spring.factories index d03cacf7e..ffadb003a 100644 --- a/springdoc-openapi-webflux-ui/src/main/resources/META-INF/spring.factories +++ b/springdoc-openapi-webflux-ui/src/main/resources/META-INF/spring.factories @@ -2,4 +2,5 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springdoc.webflux.ui.SwaggerConfig,\ org.springdoc.core.SwaggerUiConfigProperties,\ org.springdoc.core.SwaggerUiConfigParameters,\ +org.springdoc.core.SpringDocUIConfiguration,\ org.springdoc.core.SwaggerUiOAuthProperties \ No newline at end of file diff --git a/springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocTest.java b/springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocTest.java index feeb492a3..da6212d2d 100644 --- a/springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocTest.java +++ b/springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocTest.java @@ -21,6 +21,7 @@ import org.springdoc.core.Constants; import org.springdoc.core.SpringDocConfigProperties; import org.springdoc.core.SpringDocConfiguration; +import org.springdoc.core.SpringDocUIConfiguration; import org.springdoc.core.SwaggerUiConfigParameters; import org.springdoc.core.SwaggerUiConfigProperties; import org.springdoc.core.SwaggerUiOAuthProperties; @@ -38,7 +39,9 @@ @WebFluxTest -@ContextConfiguration(classes = { SpringDocConfiguration.class, SpringDocConfigProperties.class, SpringDocWebFluxConfiguration.class, SwaggerUiConfigParameters.class, SwaggerUiConfigProperties.class, SwaggerConfig.class, SwaggerUiOAuthProperties.class }) +@ContextConfiguration(classes = { SpringDocConfiguration.class, SpringDocConfigProperties.class, + SpringDocWebFluxConfiguration.class, SwaggerUiConfigParameters.class, SwaggerUiConfigProperties.class, + SwaggerConfig.class, SwaggerUiOAuthProperties.class , SpringDocUIConfiguration.class}) public abstract class AbstractSpringDocTest extends AbstractCommonTest { private static final String DEFAULT_SWAGGER_INITIALIZER_URL = Constants.DEFAULT_WEB_JARS_PREFIX_URL + Constants.SWAGGER_INITIALIZER_URL; diff --git a/springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/app22/HelloController.java b/springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/app22/HelloController.java deleted file mode 100644 index dd11328a8..000000000 --- a/springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/app22/HelloController.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * - * * Copyright 2019-2020 the original author or authors. - * * - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * https://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * - */ - -package test.org.springdoc.ui.app22; - - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - - -@RequestMapping("/foo/bar") -@RestController -public class HelloController { - - @GetMapping("/test") - public String doSomethingInteresting() { - return "OK"; - } - -} \ No newline at end of file diff --git a/springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/app22/SpringDocApp22Test.java b/springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/app22/SpringDocApp22Test.java deleted file mode 100644 index 2be0279eb..000000000 --- a/springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/app22/SpringDocApp22Test.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * * Copyright 2019-2020 the original author or authors. - * * - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * https://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * - */ - -package test.org.springdoc.ui.app22; - -import org.hamcrest.Matchers; -import org.junit.jupiter.api.Test; -import org.springdoc.core.SwaggerUiConfigProperties; -import test.org.springdoc.ui.AbstractSpringDocTest; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.web.reactive.server.WebTestClient; - -@TestPropertySource(properties = "springdoc.swagger-ui.version=4.1.0") -public class SpringDocApp22Test extends AbstractSpringDocTest { - - @Autowired - private SwaggerUiConfigProperties swaggerUiConfig; - - @Test - public void testAddSwaggerUiVersionToPath() { - WebTestClient.ResponseSpec responseSpec = webTestClient.get().uri("/swagger-ui.html").exchange() - .expectStatus().isFound(); - responseSpec.expectHeader() - .value("Location", Matchers.is("/webjars/swagger-ui/" + swaggerUiConfig.getVersion() + "/index.html")); - } - - @SpringBootApplication - static class SpringDocTestApp {} - -} \ No newline at end of file