From 4910bd912270efd693caad5763a31e7b3090157a Mon Sep 17 00:00:00 2001 From: Sambo Chea Date: Thu, 21 Apr 2022 08:57:54 +0700 Subject: [PATCH] Add uploader module and add http for servlet with service container factory and config --- .../cubetiqs/web/config/HttpServletConfig.kt | 30 ++++++++++ .../cubetiqs/web/config/OpenApiDocConfig.kt | 10 ---- .../web/controller/admin/AdminController.kt | 20 ------- .../modules/uploader/UploaderController.kt | 60 +++++++++++++++++++ .../web/modules/uploader/UploaderEntity.kt | 45 ++++++++++++++ .../web/modules/uploader/UploaderModule.kt | 6 ++ .../modules/uploader/UploaderRepository.kt | 9 +++ .../web/modules/user/UserController.kt | 14 ++--- .../cubetiqs/web/modules/user/UserEntity.kt | 1 + api/src/main/resources/application.yml | 12 ++-- 10 files changed, 166 insertions(+), 41 deletions(-) create mode 100644 api/src/main/kotlin/com/cubetiqs/web/config/HttpServletConfig.kt delete mode 100644 api/src/main/kotlin/com/cubetiqs/web/controller/admin/AdminController.kt create mode 100644 api/src/main/kotlin/com/cubetiqs/web/modules/uploader/UploaderController.kt create mode 100644 api/src/main/kotlin/com/cubetiqs/web/modules/uploader/UploaderEntity.kt create mode 100644 api/src/main/kotlin/com/cubetiqs/web/modules/uploader/UploaderModule.kt create mode 100644 api/src/main/kotlin/com/cubetiqs/web/modules/uploader/UploaderRepository.kt diff --git a/api/src/main/kotlin/com/cubetiqs/web/config/HttpServletConfig.kt b/api/src/main/kotlin/com/cubetiqs/web/config/HttpServletConfig.kt new file mode 100644 index 0000000..7ab0980 --- /dev/null +++ b/api/src/main/kotlin/com/cubetiqs/web/config/HttpServletConfig.kt @@ -0,0 +1,30 @@ +package com.cubetiqs.web.config + +import org.apache.catalina.connector.Connector +import org.springframework.beans.factory.annotation.Value +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory +import org.springframework.boot.web.servlet.server.ServletWebServerFactory +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration + +@ConditionalOnProperty(name = ["http.port"], matchIfMissing = false) +@Configuration +class HttpServletConfig( + @Value("\${http.port:8080}") + private val httpPort: Int, +) { + @Bean + fun servletContainer(): ServletWebServerFactory { + val tomcat = TomcatServletWebServerFactory() + tomcat.addAdditionalTomcatConnectors(createStandardConnector()) + return tomcat + } + + private fun createStandardConnector(): Connector { + val connector = Connector("org.apache.coyote.http11.Http11NioProtocol") + connector.port = httpPort + connector.scheme = "http" + return connector + } +} \ No newline at end of file diff --git a/api/src/main/kotlin/com/cubetiqs/web/config/OpenApiDocConfig.kt b/api/src/main/kotlin/com/cubetiqs/web/config/OpenApiDocConfig.kt index 75bfbf1..4fb275d 100644 --- a/api/src/main/kotlin/com/cubetiqs/web/config/OpenApiDocConfig.kt +++ b/api/src/main/kotlin/com/cubetiqs/web/config/OpenApiDocConfig.kt @@ -32,7 +32,6 @@ class OpenApiDocConfig @Autowired constructor( val appProperties: AppProperties, ) { companion object { - private val ADMIN_API_PATH get() = "/admin/**" private val DEFAULT_API_PATH get() = "/**" } @@ -55,19 +54,10 @@ class OpenApiDocConfig @Autowired constructor( return GroupedOpenApi.builder() .group("default") .pathsToMatch(DEFAULT_API_PATH) - .pathsToExclude("/error", ADMIN_API_PATH) .packagesToScan("com.cubetiqs.web") .build() } - @Bean - fun adminApi(): GroupedOpenApi { - return GroupedOpenApi.builder() - .group("admin") - .pathsToMatch(ADMIN_API_PATH) - .build() - } - @Bean fun cubetiqOpenAPI(): OpenAPI { return OpenAPI() diff --git a/api/src/main/kotlin/com/cubetiqs/web/controller/admin/AdminController.kt b/api/src/main/kotlin/com/cubetiqs/web/controller/admin/AdminController.kt deleted file mode 100644 index f851765..0000000 --- a/api/src/main/kotlin/com/cubetiqs/web/controller/admin/AdminController.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.cubetiqs.web.controller.admin - -import com.cubetiqs.web.annotation.ApiBearerAuth -import com.cubetiqs.web.controller.BaseController -import com.cubetiqs.web.util.RouteConstants -import io.swagger.v3.oas.annotations.tags.Tag -import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RestController - -@Tag(name = "Admin") -@RestController -@RequestMapping(RouteConstants.ADMIN) -class AdminController : BaseController { - @ApiBearerAuth - @GetMapping - fun getAdmin(): String { - return "Admin" - } -} \ No newline at end of file diff --git a/api/src/main/kotlin/com/cubetiqs/web/modules/uploader/UploaderController.kt b/api/src/main/kotlin/com/cubetiqs/web/modules/uploader/UploaderController.kt new file mode 100644 index 0000000..3a55fec --- /dev/null +++ b/api/src/main/kotlin/com/cubetiqs/web/modules/uploader/UploaderController.kt @@ -0,0 +1,60 @@ +package com.cubetiqs.web.modules.uploader + +import com.cubetiqs.web.util.RouteConstants +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.tags.Tag +import org.springdoc.core.converters.models.PageableAsQueryParam +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.data.domain.Page +import org.springframework.data.domain.Pageable +import org.springframework.web.bind.annotation.* +import java.util.* + +@UploaderModule +@Tag(name = "Uploader Controller") +@RestController +@RequestMapping(RouteConstants.INDEX + "uploader") +class UploaderController @Autowired constructor( + private val repository: UploaderRepository, +) { + @GetMapping + @PageableAsQueryParam + fun getAll( + @Parameter(hidden = true) + pageable: Pageable?, + ): Page { + return repository.findAll(pageable ?: Pageable.unpaged()) + } + + @ResponseStatus(value = org.springframework.http.HttpStatus.CREATED) + @PostMapping + fun create( + @RequestBody body: UploaderEntity + ): UploaderEntity { + return repository.save(body) + } + + @ResponseStatus(value = org.springframework.http.HttpStatus.OK) + @PutMapping("/{id}") + fun update( + @PathVariable id: String, + @RequestBody body: UploaderEntity + ): UploaderEntity { + val user = repository.findById(UUID.fromString(id)).orElseThrow { + throw IllegalArgumentException("File not found") + } + body.id = user.id + return repository.save(body) + } + + @ResponseStatus(value = org.springframework.http.HttpStatus.NO_CONTENT) + @DeleteMapping("/{id}") + fun delete( + @PathVariable id: String, + ) { + val user = repository.findById(UUID.fromString(id)).orElseThrow { + throw IllegalArgumentException("File not found") + } + repository.delete(user) + } +} \ No newline at end of file diff --git a/api/src/main/kotlin/com/cubetiqs/web/modules/uploader/UploaderEntity.kt b/api/src/main/kotlin/com/cubetiqs/web/modules/uploader/UploaderEntity.kt new file mode 100644 index 0000000..f3dfdb5 --- /dev/null +++ b/api/src/main/kotlin/com/cubetiqs/web/modules/uploader/UploaderEntity.kt @@ -0,0 +1,45 @@ +package com.cubetiqs.web.modules.uploader + +import org.hibernate.Hibernate +import java.io.Serializable +import java.util.* +import javax.persistence.* + +@UploaderModule +@Entity +@Table(name = "uploader") +open class UploaderEntity( + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + open var id: UUID? = null, + + @Column(name = "filename") + open var filename: String? = null, + + @Column(name = "content_type") + open var contentType: String? = null, + + @Column(name = "content_length") + open var contentLength: Long? = null, + + @Column(name = "path", length = 300) + open var path: String? = null, + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "created_at") + open var createdAt: Date? = null, + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "updated_at") + open var updatedAt: Date? = null, +) : Serializable { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || Hibernate.getClass(this) != Hibernate.getClass(other)) return false + other as UploaderEntity + + return id != null && id == other.id + } + + override fun hashCode(): Int = javaClass.hashCode() +} \ No newline at end of file diff --git a/api/src/main/kotlin/com/cubetiqs/web/modules/uploader/UploaderModule.kt b/api/src/main/kotlin/com/cubetiqs/web/modules/uploader/UploaderModule.kt new file mode 100644 index 0000000..7ee84dd --- /dev/null +++ b/api/src/main/kotlin/com/cubetiqs/web/modules/uploader/UploaderModule.kt @@ -0,0 +1,6 @@ +package com.cubetiqs.web.modules.uploader + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty + +@ConditionalOnProperty(name = ["module.uploader.enabled", "spring.datasource.enabled"], havingValue = "true") +annotation class UploaderModule \ No newline at end of file diff --git a/api/src/main/kotlin/com/cubetiqs/web/modules/uploader/UploaderRepository.kt b/api/src/main/kotlin/com/cubetiqs/web/modules/uploader/UploaderRepository.kt new file mode 100644 index 0000000..0f6645c --- /dev/null +++ b/api/src/main/kotlin/com/cubetiqs/web/modules/uploader/UploaderRepository.kt @@ -0,0 +1,9 @@ +package com.cubetiqs.web.modules.uploader + +import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.stereotype.Repository +import java.util.* + +@UploaderModule +@Repository +interface UploaderRepository : JpaRepository \ No newline at end of file diff --git a/api/src/main/kotlin/com/cubetiqs/web/modules/user/UserController.kt b/api/src/main/kotlin/com/cubetiqs/web/modules/user/UserController.kt index 63fd5d3..ba211e8 100644 --- a/api/src/main/kotlin/com/cubetiqs/web/modules/user/UserController.kt +++ b/api/src/main/kotlin/com/cubetiqs/web/modules/user/UserController.kt @@ -15,7 +15,7 @@ import java.util.* @RestController @RequestMapping(RouteConstants.INDEX + "user") class UserController @Autowired constructor( - private val userRepository: UserRepository, + private val repository: UserRepository, ) { @GetMapping @PageableAsQueryParam @@ -23,7 +23,7 @@ class UserController @Autowired constructor( @Parameter(hidden = true) pageable: Pageable?, ): Page { - return userRepository.findAll(pageable ?: Pageable.unpaged()) + return repository.findAll(pageable ?: Pageable.unpaged()) } @ResponseStatus(value = org.springframework.http.HttpStatus.CREATED) @@ -31,7 +31,7 @@ class UserController @Autowired constructor( fun create( @RequestBody body: UserEntity ): UserEntity { - return userRepository.save(body) + return repository.save(body) } @ResponseStatus(value = org.springframework.http.HttpStatus.OK) @@ -40,11 +40,11 @@ class UserController @Autowired constructor( @PathVariable id: String, @RequestBody body: UserEntity ): UserEntity { - val user = userRepository.findById(UUID.fromString(id)).orElseThrow { + val user = repository.findById(UUID.fromString(id)).orElseThrow { throw IllegalArgumentException("User not found") } body.id = user.id - return userRepository.save(body) + return repository.save(body) } @ResponseStatus(value = org.springframework.http.HttpStatus.NO_CONTENT) @@ -52,9 +52,9 @@ class UserController @Autowired constructor( fun delete( @PathVariable id: String, ) { - val user = userRepository.findById(UUID.fromString(id)).orElseThrow { + val user = repository.findById(UUID.fromString(id)).orElseThrow { throw IllegalArgumentException("User not found") } - userRepository.delete(user) + repository.delete(user) } } \ No newline at end of file diff --git a/api/src/main/kotlin/com/cubetiqs/web/modules/user/UserEntity.kt b/api/src/main/kotlin/com/cubetiqs/web/modules/user/UserEntity.kt index 3cbcec2..61c4817 100644 --- a/api/src/main/kotlin/com/cubetiqs/web/modules/user/UserEntity.kt +++ b/api/src/main/kotlin/com/cubetiqs/web/modules/user/UserEntity.kt @@ -5,6 +5,7 @@ import java.io.Serializable import java.util.* import javax.persistence.* +@UserModule @Entity @Table(name = "user") open class UserEntity( diff --git a/api/src/main/resources/application.yml b/api/src/main/resources/application.yml index a162a25..d438a01 100644 --- a/api/src/main/resources/application.yml +++ b/api/src/main/resources/application.yml @@ -1,5 +1,7 @@ +http: + port: ${HTTP_PORT:8080} server: - port: ${SERVER_PORT:8080} + port: ${SERVER_PORT:8443} ssl: key-store: ${SERVER_SSL_KEY_STORE:classpath:keystore/server.jks} key-store-password: ${SERVER_SSL_KEY_STORE_PASSWORD:cubetiq} @@ -12,7 +14,7 @@ spring: profiles: active: ${APP_PROFILE:demo} application: - name: cubetiq-api-service + name: ${SERVICE_NAME:cubetiq-api-service} redis: enabled: ${REDIS_ENABLED:false} host: ${REDIS_HOST:localhost} @@ -30,12 +32,14 @@ spring: module: user: enabled: ${MODULE_USER_ENABLED:true} + uploader: + enabled: ${MODULE_UPLOADER_ENABLED:true} cubetiq: app: data-dir: ${APP_DATA_DIR:${user.home}/${spring.application.name}} - name: CUBETIQ Web API - description: CUBETIQ Spring Web API's Documentation + name: ${APP_NAME:CUBETIQ Web API} + description: ${APP_DESCRIPTION:CUBETIQ Spring Web API's Documentation} logging: file: