diff --git a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/TenantsController.java b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/TenantsController.java index 4bb89e416..d28a3efdc 100644 --- a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/TenantsController.java +++ b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/TenantsController.java @@ -14,8 +14,10 @@ import org.springframework.web.bind.annotation.RestController; import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException; import com.iqser.red.service.persistence.management.v1.processor.service.DeploymentKeyService; import com.iqser.red.service.persistence.management.v1.processor.service.TenantManagementService; +import com.iqser.red.service.persistence.management.v1.processor.utils.MagicConverter; import com.iqser.red.service.persistence.service.v1.api.external.resource.TenantsResource; import com.iqser.red.service.persistence.service.v1.api.shared.model.common.JSONPrimitive; +import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.SimpleTenantResponse; import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.TenantRequest; import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.TenantResponse; @@ -53,4 +55,9 @@ public class TenantsController implements TenantsResource { return JSONPrimitive.of(deploymentKeyService.getDeploymentKey(tenantId)); } + + public List getSimpleTenants() { + return MagicConverter.convert(tenantManagementService.getTenants(), SimpleTenantResponse.class); + } + } 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..0a39a7aba --- /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,47 @@ +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) { + + var cleanedUpPath = path.contains("?") ? path.substring(0, path.indexOf("?")) : path; + registry.addInterceptor(new DocsInterceptor()).addPathPatterns(cleanedUpPath); + } + + + 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-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/TenantsResource.java b/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/TenantsResource.java index 4e890cf87..35de894da 100644 --- a/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/TenantsResource.java +++ b/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/TenantsResource.java @@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.ResponseStatus; import com.iqser.red.service.persistence.service.v1.api.shared.model.common.JSONPrimitive; +import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.SimpleTenantResponse; import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.TenantRequest; import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.TenantResponse; @@ -36,6 +37,11 @@ public interface TenantsResource { @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")}) List getTenants(); + @GetMapping(value = ExternalApi.BASE_PATH + "/tenants/simple", produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Gets all existing tenant in a simplified format", description = "None") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")}) + List getSimpleTenants(); + @GetMapping(value = ExternalApi.BASE_PATH + "/deploymentKey" + TENANT_ID_PATH_PARAM, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(summary = "Returns the deployment key for a tenant", description = "None") 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'] diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/multitenancy/SimpleTenantResponse.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/multitenancy/SimpleTenantResponse.java new file mode 100644 index 000000000..b90dfe359 --- /dev/null +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/multitenancy/SimpleTenantResponse.java @@ -0,0 +1,18 @@ +package com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class SimpleTenantResponse { + + private String tenantId; + private String displayName; + private String guid; + +}