From 0c1afb6e58df334ae4a92389bebd270440a6463d Mon Sep 17 00:00:00 2001 From: Timo Bejan Date: Wed, 22 Mar 2023 13:19:06 +0200 Subject: [PATCH] RED-4515 - Swagger multitenancy --- .../swagger/SwaggerAutoConfiguration.java | 9 +--- .../swagger/SwaggerCustomDocsController.java | 54 +++++++++++++++++++ .../swagger/SwaggerTenantMvcConfigurer.java | 46 ++++++++++++++++ .../src/main/resources/application.yml | 3 +- 4 files changed, 104 insertions(+), 8 deletions(-) create mode 100644 persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/swagger/SwaggerCustomDocsController.java create mode 100644 persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/swagger/SwaggerTenantMvcConfigurer.java diff --git a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/swagger/SwaggerAutoConfiguration.java b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/swagger/SwaggerAutoConfiguration.java index 4376f8e69..0466f3847 100644 --- a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/swagger/SwaggerAutoConfiguration.java +++ b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/swagger/SwaggerAutoConfiguration.java @@ -50,10 +50,7 @@ public class SwaggerAutoConfiguration { private static final String DESCRIPTION = "Description for redaction"; private static final String VERSION = "1.0"; private static final String OAUTH_NAME = "RED-OAUTH"; - private static final String PROTOCOL_URL_FORMAT = "/auth/realms/%s/protocol/openid-connect"; - - @Autowired - private KeycloakSpringBootProperties keycloakProperties; + private static final String PROTOCOL_URL_FORMAT = "/auth/realms//protocol/openid-connect"; @Bean @@ -128,9 +125,7 @@ public class SwaggerAutoConfiguration { private OAuthFlow createAuthorizationCodeFlow() { - var protocolUrl = String.format(PROTOCOL_URL_FORMAT, keycloakProperties.getRealm()); - - return new OAuthFlow().authorizationUrl(protocolUrl + "/auth").tokenUrl(protocolUrl + "/token"); + return new OAuthFlow().authorizationUrl(PROTOCOL_URL_FORMAT + "/auth").tokenUrl(PROTOCOL_URL_FORMAT + "/token"); } } diff --git a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/swagger/SwaggerCustomDocsController.java b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/swagger/SwaggerCustomDocsController.java new file mode 100644 index 000000000..f0b7b0191 --- /dev/null +++ b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/swagger/SwaggerCustomDocsController.java @@ -0,0 +1,54 @@ +package com.iqser.red.persistence.service.v1.external.api.impl.swagger; + +import java.util.Locale; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import org.springdoc.webmvc.api.OpenApiWebMvcResource; +import org.springdoc.webmvc.ui.SwaggerConfigResource; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.iqser.red.service.persistence.service.v1.api.external.resource.ExternalApi; + +import io.swagger.v3.oas.annotations.Operation; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; + +@RestController +@RequiredArgsConstructor +public class SwaggerCustomDocsController { + + private final OpenApiWebMvcResource openApiWebMvcResource; + + private final SwaggerConfigResource swaggerConfigResource; + + @Value("${springdoc.api-docs.path:#{T(org.springdoc.core.Constants).DEFAULT_API_DOCS_URL}}") + private String apiDocsUrl; + + + @SneakyThrows + @Operation(hidden = true) + @GetMapping(ExternalApi.BASE_PATH + "/docs/tenant") + public String getDocs(HttpServletRequest request, @RequestParam(value = "tenantId", required = false, defaultValue = "redaction") String tenantId) { + + var response = openApiWebMvcResource.openapiJson(request, apiDocsUrl, Locale.getDefault()); + return response.replace("", tenantId); + + } + + + @Operation(hidden = true) + @GetMapping(value = "/redaction-gateway-v1/docs/swagger-config", produces = MediaType.APPLICATION_JSON_VALUE) + public Map getSwaggerUiConfig(HttpServletRequest request) { + + var map = swaggerConfigResource.openapiJson(request); + map.put("url", apiDocsUrl); + return map; + } + +} diff --git a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/swagger/SwaggerTenantMvcConfigurer.java b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/swagger/SwaggerTenantMvcConfigurer.java new file mode 100644 index 000000000..949370b3c --- /dev/null +++ b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/swagger/SwaggerTenantMvcConfigurer.java @@ -0,0 +1,46 @@ +package com.iqser.red.persistence.service.v1.external.api.impl.swagger; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import com.iqser.red.service.persistence.service.v1.api.external.resource.ExternalApi; + +@Configuration +@EnableWebMvc +public class SwaggerTenantMvcConfigurer implements WebMvcConfigurer { + + @Value("${springdoc.api-docs.path:#{T(org.springdoc.core.Constants).DEFAULT_API_DOCS_URL}}") + private String path; + + + @Override + public void addInterceptors(InterceptorRegistry registry) { + + registry.addInterceptor(new DocsInterceptor()).addPathPatterns(path.substring(0,path.indexOf("?"))); + } + + + public static class DocsInterceptor implements HandlerInterceptor { + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + + var query = ""; + if (!StringUtils.isBlank(request.getQueryString())) { + query = "?" + request.getQueryString(); + } + response.sendRedirect(ExternalApi.BASE_PATH + "/docs/tenant" + query); + return false; + } + + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yml b/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yml index f92385ce8..c0a1e0fbb 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yml +++ b/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yml @@ -157,8 +157,9 @@ springdoc: client-id: swagger-ui-client doc-expansion: none enabled: ${swagger.enabled} + config-url: /redaction-gateway-v1/docs/swagger-config api-docs: - path: /redaction-gateway-v1/docs + path: /redaction-gateway-v1/docs?tenantId=redaction enabled: ${swagger.enabled} pre-loading-enabled: true packages-to-scan: ['com.iqser.red.persistence.service.v1.external.api']