From fe1194949fc2b96a483debb9e4c23dea370d185f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Kope=C4=87?= Date: Mon, 29 Jun 2020 21:44:09 -0700 Subject: [PATCH] New configuration properties Add property to always add a generated server to the server's list. Add property for adding a custom suffix to the generated server hostname. --- .../api/AbstractOpenApiResource.java | 27 +++++----- .../org/springdoc/core/OpenAPIBuilder.java | 15 ++++-- .../core/SpringDocConfigProperties.java | 27 ++++++++++ .../api/app124/SpringDocApp124Test.java | 48 ++++++++++++++++++ .../api/app124/SpringDocTestApp.java | 49 +++++++++++++++++++ .../api/app125/SpringDocApp125Test.java | 46 +++++++++++++++++ .../api/app125/SpringDocTestApp.java | 33 +++++++++++++ .../src/test/resources/results/app124.json | 19 +++++++ .../src/test/resources/results/app125.json | 15 ++++++ 9 files changed, 262 insertions(+), 17 deletions(-) create mode 100644 springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app124/SpringDocApp124Test.java create mode 100644 springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app124/SpringDocTestApp.java create mode 100644 springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app125/SpringDocApp125Test.java create mode 100644 springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app125/SpringDocTestApp.java create mode 100644 springdoc-openapi-webmvc-core/src/test/resources/results/app124.json create mode 100644 springdoc-openapi-webmvc-core/src/test/resources/results/app125.json diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java b/springdoc-openapi-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java index b1a9a759f..8744a88ac 100644 --- a/springdoc-openapi-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java +++ b/springdoc-openapi-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java @@ -89,6 +89,7 @@ /** * The type Abstract open api resource. * @author bnasslahsen + * @author Maciej Kopeć */ public abstract class AbstractOpenApiResource extends SpecFilter { @@ -215,18 +216,28 @@ public static void addHiddenRestControllers(Class... classes) { * @param classes the classes */ public static void addHiddenRestControllers(String... classes) { - Set> hiddenClasses =new HashSet<>(); + Set> hiddenClasses = new HashSet<>(); for (String aClass : classes) { try { hiddenClasses.add(Class.forName(aClass)); } catch (ClassNotFoundException e) { - LOGGER.warn("The following class doesn't exist and cannot be hidden: {}", aClass); + LOGGER.warn("The following class doesn't exist and cannot be hidden: {}", aClass); } } HIDDEN_REST_CONTROLLERS.addAll(hiddenClasses); } + /** + * Is hidden rest controllers boolean. + * + * @param rawClass the raw class + * @return the boolean + */ + public static boolean isHiddenRestControllers(Class rawClass) { + return HIDDEN_REST_CONTROLLERS.stream().anyMatch(clazz -> clazz.isAssignableFrom(rawClass)); + } + /** * Gets open api. * @@ -252,7 +263,7 @@ protected synchronized OpenAPI getOpenApi() { // run the optional customisers openApiCustomisers.ifPresent(apiCustomisers -> apiCustomisers.forEach(openApiCustomiser -> openApiCustomiser.customise(openApi))); if (!CollectionUtils.isEmpty(openApi.getServers())) - openAPIBuilder.setServersPresent(true); + openAPIBuilder.setServersPresent(!springDocConfigProperties.isAlwaysAddGeneratedServer()); openAPIBuilder.updateServers(openApi); if (springDocConfigProperties.isRemoveBrokenReferenceDefinitions()) @@ -590,16 +601,6 @@ protected boolean isAdditionalRestController(Class rawClass) { return ADDITIONAL_REST_CONTROLLERS.stream().anyMatch(clazz -> clazz.isAssignableFrom(rawClass)); } - /** - * Is hidden rest controllers boolean. - * - * @param rawClass the raw class - * @return the boolean - */ - public static boolean isHiddenRestControllers(Class rawClass) { - return HIDDEN_REST_CONTROLLERS.stream().anyMatch(clazz -> clazz.isAssignableFrom(rawClass)); - } - /** * Gets default allowed http methods. * diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/OpenAPIBuilder.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/OpenAPIBuilder.java index f0ee15886..196f6f9d8 100644 --- a/springdoc-openapi-common/src/main/java/org/springdoc/core/OpenAPIBuilder.java +++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/OpenAPIBuilder.java @@ -49,6 +49,7 @@ import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.security.SecurityScheme; import io.swagger.v3.oas.models.servers.Server; +import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -75,6 +76,7 @@ /** * The type Open api builder. * @author bnasslahsen + * @author Maciej Kopeć */ public class OpenAPIBuilder { @@ -223,10 +225,15 @@ else if (calculatedOpenAPI.getInfo() == null) { public OpenAPI updateServers(OpenAPI openAPI) { if (!isServersPresent) // default server value { - Server server = new Server().url(serverBaseUrl).description(DEFAULT_SERVER_DESCRIPTION); - List servers = new ArrayList(); - servers.add(server); - openAPI.setServers(servers); + final Server generatedServer = new Server() + .url(serverBaseUrl + springDocConfigProperties.getGeneratedServerSuffix()) + .description(DEFAULT_SERVER_DESCRIPTION); + + final List servers = ObjectUtils.defaultIfNull(openAPI.getServers(), new ArrayList<>()); + + if (!servers.contains(generatedServer)) { + openAPI.addServersItem(generatedServer); + } } return openAPI; } diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocConfigProperties.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocConfigProperties.java index 5324c5939..4114f914c 100644 --- a/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocConfigProperties.java +++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocConfigProperties.java @@ -34,6 +34,7 @@ /** * The type Spring doc config properties. * @author bnasslahsen + * @author Maciej Kopeć */ @Configuration @ConfigurationProperties(prefix = Constants.SPRINGDOC_PREFIX) @@ -120,6 +121,16 @@ public class SpringDocConfigProperties { */ private String defaultProducesMediaType = MediaType.ALL_VALUE; + /** + * Always add a generated server to server's list + */ + private boolean alwaysAddGeneratedServer = false; + + /** + * Add a suffix to a generated server's host. + */ + private String generatedServerSuffix = ""; + /** * Is auto tag classes boolean. * @@ -426,6 +437,22 @@ public void setWriterWithDefaultPrettyPrinter(boolean writerWithDefaultPrettyPri this.writerWithDefaultPrettyPrinter = writerWithDefaultPrettyPrinter; } + public boolean isAlwaysAddGeneratedServer() { + return alwaysAddGeneratedServer; + } + + public void setAlwaysAddGeneratedServer(boolean alwaysAddGeneratedServer) { + this.alwaysAddGeneratedServer = alwaysAddGeneratedServer; + } + + public String getGeneratedServerSuffix() { + return generatedServerSuffix; + } + + public void setGeneratedServerSuffix(String generatedServerSuffix) { + this.generatedServerSuffix = generatedServerSuffix; + } + /** * The type Webjars. * @author bnasslahsen diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app124/SpringDocApp124Test.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app124/SpringDocApp124Test.java new file mode 100644 index 000000000..141940ac6 --- /dev/null +++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app124/SpringDocApp124Test.java @@ -0,0 +1,48 @@ +/* + * + * * 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.api.app124; + +import org.junit.jupiter.api.Test; +import org.springdoc.core.Constants; +import test.org.springdoc.api.AbstractSpringDocTest; + +import org.springframework.test.context.TestPropertySource; + +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static test.org.springdoc.api.app124.SpringDocTestApp.SERVER_HOSTNAME; + +/** + * @author Maciej Kopeć + */ +@TestPropertySource(properties = "springdoc.always-add-generated-server=true") +public class SpringDocApp124Test extends AbstractSpringDocTest { + + @Test + public void testAlwaysAddGeneratedServer() throws Exception { + mockMvc.perform(get(Constants.DEFAULT_API_DOCS_URL)).andExpect(status().isOk()) + .andExpect(jsonPath("$.openapi", is("3.0.1"))) + .andExpect(jsonPath("$.servers", hasSize(2))) + .andExpect(jsonPath("$.servers[0].url", is(SERVER_HOSTNAME))) + .andExpect(jsonPath("$.servers[1].url", is("http://localhost"))); + } +} diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app124/SpringDocTestApp.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app124/SpringDocTestApp.java new file mode 100644 index 000000000..3d86f44ab --- /dev/null +++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app124/SpringDocTestApp.java @@ -0,0 +1,49 @@ +/* + * + * * 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.api.app124; + +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.servers.Server; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; + +/** + * @author Maciej Kopeć + */ +@SpringBootApplication +public class SpringDocTestApp { + + public static final String SERVER_HOSTNAME = "https:://hostname.org/"; + + public static void main(String[] args) { + SpringApplication.run(SpringDocTestApp.class, args); + } + + @Bean + public OpenAPI customOpenAPI() { + return new OpenAPI() + .addServersItem( + new Server() + .url(SERVER_HOSTNAME) + .description("Super API") + ); + } +} diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app125/SpringDocApp125Test.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app125/SpringDocApp125Test.java new file mode 100644 index 000000000..1f8dafa58 --- /dev/null +++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app125/SpringDocApp125Test.java @@ -0,0 +1,46 @@ +/* + * + * * 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.api.app125; + +import org.junit.jupiter.api.Test; +import org.springdoc.core.Constants; +import test.org.springdoc.api.AbstractSpringDocTest; + +import org.springframework.test.context.TestPropertySource; + +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * @author Maciej Kopeć + */ +@TestPropertySource(properties = "springdoc.generated-server-suffix=/suffix") +public class SpringDocApp125Test extends AbstractSpringDocTest { + + @Test + public void testAddSuffixToGeneratedServer() throws Exception { + mockMvc.perform(get(Constants.DEFAULT_API_DOCS_URL)).andExpect(status().isOk()) + .andExpect(jsonPath("$.openapi", is("3.0.1"))) + .andExpect(jsonPath("$.servers", hasSize(1))) + .andExpect(jsonPath("$.servers[0].url", is("http://localhost/suffix"))); + } +} diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app125/SpringDocTestApp.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app125/SpringDocTestApp.java new file mode 100644 index 000000000..6f320685e --- /dev/null +++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app125/SpringDocTestApp.java @@ -0,0 +1,33 @@ +/* + * + * * 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.api.app125; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author Maciej Kopeć + */ +@SpringBootApplication +public class SpringDocTestApp { + + public static void main(String[] args) { + SpringApplication.run(SpringDocTestApp.class, args); + } +} diff --git a/springdoc-openapi-webmvc-core/src/test/resources/results/app124.json b/springdoc-openapi-webmvc-core/src/test/resources/results/app124.json new file mode 100644 index 000000000..e0d4089e0 --- /dev/null +++ b/springdoc-openapi-webmvc-core/src/test/resources/results/app124.json @@ -0,0 +1,19 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "OpenAPI definition", + "version": "v0" + }, + "servers": [ + { + "url":"https:://hostname.org/", + "description":"Super API" + }, + { + "url": "http://localhost", + "description": "Generated server url" + } + ], + "paths": {}, + "components": {} +} diff --git a/springdoc-openapi-webmvc-core/src/test/resources/results/app125.json b/springdoc-openapi-webmvc-core/src/test/resources/results/app125.json new file mode 100644 index 000000000..73471026d --- /dev/null +++ b/springdoc-openapi-webmvc-core/src/test/resources/results/app125.json @@ -0,0 +1,15 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "OpenAPI definition", + "version": "v0" + }, + "servers": [ + { + "url": "http://localhost/suffix", + "description": "Generated server url" + } + ], + "paths": {}, + "components": {} +}