Upgrade spring web modules from springfox to springdoc openapi and deps

This commit is contained in:
Sambo Chea 2021-12-11 11:53:10 +07:00
parent 198644cbd1
commit 6d1ebcc414
Signed by: sombochea
GPG Key ID: 3C7CF22A05D95490
9 changed files with 134 additions and 106 deletions

View File

@ -32,8 +32,8 @@ springBoot {
} }
dependencies { dependencies {
// SWAGGER - FRAMEWORK // Migrating from SpringFox
implementation("io.springfox:springfox-boot-starter:3.0.0") implementation("org.springdoc:springdoc-openapi-ui:1.5.13")
// SPRING FRAMEWORK AND CORE // SPRING FRAMEWORK AND CORE
implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.boot:spring-boot-starter-web")

View File

@ -0,0 +1,60 @@
package com.cubetiqs.web.config
import io.swagger.v3.oas.models.ExternalDocumentation
import io.swagger.v3.oas.models.OpenAPI
import io.swagger.v3.oas.models.info.Info
import io.swagger.v3.oas.models.info.License
import org.springdoc.core.GroupedOpenApi
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration
class SpringDocConfig {
companion object {
private val PUBLIC_API_PATH get() = "/public/**"
private val ADMIN_API_PATH get() = "/admin/**"
private val DEFAULT_API_PATH get() = "/**"
}
@Bean
fun defaultApi(): GroupedOpenApi {
return GroupedOpenApi.builder()
.group("default-api")
.pathsToMatch(DEFAULT_API_PATH)
.pathsToExclude("/error", PUBLIC_API_PATH, ADMIN_API_PATH)
.packagesToScan("com.cubetiqs.web")
.build()
}
@Bean
fun publicApi(): GroupedOpenApi {
return GroupedOpenApi.builder()
.group("public-api")
.pathsToMatch(PUBLIC_API_PATH)
.build()
}
@Bean
fun adminApi(): GroupedOpenApi {
return GroupedOpenApi.builder()
.group("admin-api")
.pathsToMatch(ADMIN_API_PATH)
.build()
}
@Bean
fun cubetiqOpenAPI(): OpenAPI {
return OpenAPI()
.info(
Info().title("CUBETIQ Web API")
.description("CUBETIQ Spring Web API Application")
.version("v0.0.1")
.license(License().name("Apache 2.0").url("https://cubetiqs.com"))
)
.externalDocs(
ExternalDocumentation()
.description("CUBETIQ Web Wiki Documentation")
.url("https://cubetiqs.com")
)
}
}

View File

@ -1,78 +0,0 @@
package com.cubetiqs.web.config
import com.cubetiqs.web.property.AppProperties
import com.cubetiqs.web.util.AppConstants
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.info.BuildProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import springfox.documentation.builders.ApiInfoBuilder
import springfox.documentation.builders.PathSelectors
import springfox.documentation.builders.RequestHandlerSelectors
import springfox.documentation.service.*
import springfox.documentation.spi.DocumentationType
import springfox.documentation.spi.service.contexts.SecurityContext
import springfox.documentation.spring.web.plugins.Docket
@Configuration
class SpringFoxConfig @Autowired constructor(
val buildProperties: BuildProperties,
val appProperties: AppProperties,
) {
companion object {
private const val AUTHORIZATION_KEY: String = "Bearer"
private const val AUTHORIZATION_HEADER: String = "Authorization"
}
private fun defaultAuth(): List<SecurityReference> {
val authorizationScope = AuthorizationScope("global", "accessEverything")
val authorizationScopes: Array<AuthorizationScope?> = arrayOfNulls(1)
authorizationScopes[0] = authorizationScope
return listOf(SecurityReference(AUTHORIZATION_KEY, authorizationScopes))
}
private fun securityContext(): SecurityContext? {
return SecurityContext.builder()
.securityReferences(defaultAuth())
.build()
}
@Bean
fun api(): Docket {
return Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage(AppConstants.BASE_PACKAGE_API_DOCS))
.paths(PathSelectors.any())
.build()
.securityContexts(listOf(securityContext()))
.securitySchemes(listOf(apiKey()))
.apiInfo(apiInfo())
// Allow to configurable custom pagination of request in swagger ui //
// .directModelSubstitute(Pageable::class.java, SwaggerPageable::class.java)
// .directModelSubstitute(UrlParamable::class.java, UrlParamableSwaggerView::class.java)
}
private fun apiInfo(): ApiInfo {
return ApiInfoBuilder()
.description(appProperties.appDescription)
.title(appProperties.appName)
.version(buildProperties.version)
.contact(
Contact(
"CUBETIQ Solution",
"https://cubetiqs.com",
"ops@cubetiqs.com",
)
)
.build()
}
private fun apiKey(): ApiKey {
return ApiKey(
AUTHORIZATION_KEY,
AUTHORIZATION_HEADER,
"header",
)
}
}

View File

@ -1,11 +1,11 @@
package com.cubetiqs.web.controller package com.cubetiqs.web.controller
import io.swagger.v3.oas.annotations.Hidden
import org.springframework.stereotype.Controller import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.servlet.view.RedirectView import org.springframework.web.servlet.view.RedirectView
import springfox.documentation.annotations.ApiIgnore
@ApiIgnore @Hidden
@Controller @Controller
class ApiDoc { class ApiDoc {
@GetMapping(value = [ "/api-doc", "/api-docs"]) @GetMapping(value = [ "/api-doc", "/api-docs"])

View File

@ -4,10 +4,10 @@ import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity import org.springframework.http.ResponseEntity
interface BaseController { interface BaseController {
fun response( fun <T> response(
data: Any?, data: T?,
status: HttpStatus = HttpStatus.OK, status: HttpStatus = HttpStatus.OK,
): ResponseEntity<Any?> { ): ResponseEntity<T?> {
return ResponseEntity.status(status).body(data) return ResponseEntity.status(status).body(data)
} }
} }

View File

@ -1,6 +1,10 @@
package com.cubetiqs.web.controller package com.cubetiqs.web.controller
import com.cubetiqs.web.model.response.ApiInfoAuthorResponse
import com.cubetiqs.web.model.response.ApiInfoResponse
import com.cubetiqs.web.model.response.HealthResponse
import com.cubetiqs.web.util.RouteConstants import com.cubetiqs.web.util.RouteConstants
import io.swagger.v3.oas.annotations.tags.Tag
import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.info.BuildProperties import org.springframework.boot.info.BuildProperties
import org.springframework.core.env.Environment import org.springframework.core.env.Environment
@ -8,9 +12,8 @@ import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController import org.springframework.web.bind.annotation.RestController
import springfox.documentation.annotations.ApiIgnore
@ApiIgnore @Tag(name = "Miscellaneous")
@RestController @RestController
@RequestMapping(RouteConstants.INDEX) @RequestMapping(RouteConstants.INDEX)
class IndexController @Autowired constructor( class IndexController @Autowired constructor(
@ -18,25 +21,27 @@ class IndexController @Autowired constructor(
private val environment: Environment, private val environment: Environment,
) : BaseController { ) : BaseController {
@GetMapping @GetMapping
fun index(): ResponseEntity<Any?> { fun index(): ResponseEntity<ApiInfoResponse?> {
val view = mutableMapOf<String, Any?>() val authors = listOf(
view["info"] = "API Operation is running normally on ${environment.activeProfiles.joinToString(separator = ",")}" ApiInfoAuthorResponse(name = "Sambo Chea", email = "sombochea@cubetiqs.com"),
view["name"] = buildProperties.name ApiInfoAuthorResponse(name = "CUBETIQ OSS", email = "oss@cubetiqs.com"),
view["service"] = buildProperties.artifact
view["version"] = buildProperties.version
view["date"] = buildProperties.time
view["commit"] = buildProperties["commitId"]
view["authors"] = listOf(
mapOf(
"name" to "Sambo Chea",
"email" to "sombochea@cubetiqs.com",
),
mapOf(
"name" to "CUBETIQ OSS",
"email" to "oss@cubetiqs.com",
)
) )
val response = ApiInfoResponse(
info = "API Operation is running normally on ${environment.activeProfiles.joinToString(separator = ",")}",
name = buildProperties.name,
service = buildProperties.artifact,
version = buildProperties.version,
date = buildProperties.time.toString(),
commit = buildProperties["commitId"],
authors = authors,
)
return response(response)
}
return response(view) @GetMapping("/health")
fun health(): ResponseEntity<HealthResponse?> {
return response(
HealthResponse.UP
)
} }
} }

View File

@ -0,0 +1,20 @@
package com.cubetiqs.web.model.response
import io.swagger.v3.oas.annotations.media.Schema
@Schema(name = "ApiInfoResponse", description = "ApiInfoResponse")
data class ApiInfoResponse(
val name: String,
val info: String,
val service: String,
val version: String,
val date: String,
val commit: String,
val authors: Collection<ApiInfoAuthorResponse> = listOf(),
) : BaseRequestModel
@Schema(name = "ApiInfoAuthorResponse", description = "ApiInfoAuthorResponse")
data class ApiInfoAuthorResponse(
val name: String,
val email: String,
) : BaseRequestModel

View File

@ -0,0 +1,16 @@
package com.cubetiqs.web.model.response
import io.swagger.v3.oas.annotations.media.Schema
@Schema(name = "HealthResponse", description = "HealthResponse")
data class HealthResponse(
@Schema(name = "status", description = "Status for the service")
val status: String,
) : BaseRequestModel {
companion object {
private const val STATUS_UP = "UP"
private const val STATUS_DOWN = "DOWN"
val UP get() = HealthResponse(STATUS_UP)
val DOWN get() = HealthResponse(STATUS_DOWN)
}
}

View File

@ -14,3 +14,8 @@ logging:
file: file:
path: ${LOGGING_FILE_PATH:${cubetiq.app.data-dir}/logs/} path: ${LOGGING_FILE_PATH:${cubetiq.app.data-dir}/logs/}
name: ${logging.file.path}/app.log name: ${logging.file.path}/app.log
springdoc:
api-docs:
enabled: true
swagger-ui:
path: /swagger-ui