Task: Add spring web modules for general purpose to use for extenal and internal modules and projects
This commit is contained in:
parent
b9d274511f
commit
8386eaf682
37
api/.gitignore
vendored
Normal file
37
api/.gitignore
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
HELP.md
|
||||||
|
.gradle
|
||||||
|
build/
|
||||||
|
!gradle/wrapper/gradle-wrapper.jar
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
bin/
|
||||||
|
!**/src/main/**/bin/
|
||||||
|
!**/src/test/**/bin/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
out/
|
||||||
|
!**/src/main/**/out/
|
||||||
|
!**/src/test/**/out/
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
52
api/build.gradle.kts
Normal file
52
api/build.gradle.kts
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import java.io.ByteArrayOutputStream
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("org.springframework.boot")
|
||||||
|
id("io.spring.dependency-management")
|
||||||
|
kotlin("jvm")
|
||||||
|
kotlin("plugin.spring")
|
||||||
|
}
|
||||||
|
|
||||||
|
val kotlinVersion = "1.4.32"
|
||||||
|
val springBootVersion = "2.4.5"
|
||||||
|
|
||||||
|
// find the last commit
|
||||||
|
fun getGitHashLastCommit(): String {
|
||||||
|
val stdout = ByteArrayOutputStream()
|
||||||
|
exec {
|
||||||
|
commandLine("git", "rev-parse", "HEAD")
|
||||||
|
standardOutput = stdout
|
||||||
|
}
|
||||||
|
|
||||||
|
return stdout.toString().trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
springBoot {
|
||||||
|
buildInfo {
|
||||||
|
properties {
|
||||||
|
additional["commitId"] = getGitHashLastCommit()
|
||||||
|
additional["springBootVersion"] = springBootVersion
|
||||||
|
additional["kotlinVersion"] = kotlinVersion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// SWAGGER - FRAMEWORK
|
||||||
|
implementation("io.springfox:springfox-boot-starter:3.0.0")
|
||||||
|
|
||||||
|
// SPRING FRAMEWORK AND CORE
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-web")
|
||||||
|
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
|
||||||
|
|
||||||
|
// Development Runtime
|
||||||
|
developmentOnly("org.springframework.boot:spring-boot-devtools")
|
||||||
|
|
||||||
|
implementation("org.jetbrains.kotlin:kotlin-reflect")
|
||||||
|
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
||||||
|
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<Test> {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
BIN
api/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
api/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
api/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
api/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
11
api/src/main/kotlin/com/cubetiqs/web/ApiApplication.kt
Normal file
11
api/src/main/kotlin/com/cubetiqs/web/ApiApplication.kt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package com.cubetiqs.web
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||||
|
import org.springframework.boot.runApplication
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
class ApiApplication
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
runApplication<ApiApplication>(*args)
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.cubetiqs.web
|
||||||
|
|
||||||
|
import com.cubetiqs.web.stereotype.FunctionComponent
|
||||||
|
import org.springframework.context.annotation.Lazy
|
||||||
|
|
||||||
|
@FunctionComponent
|
||||||
|
@Lazy(false)
|
||||||
|
class StaticContextInitializer {
|
||||||
|
init {
|
||||||
|
println("Static context is loaded...!")
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package com.cubetiqs.web.config
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Configuration
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
class DefaultConfig
|
@ -0,0 +1,78 @@
|
|||||||
|
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",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
15
api/src/main/kotlin/com/cubetiqs/web/controller/ApiDoc.kt
Normal file
15
api/src/main/kotlin/com/cubetiqs/web/controller/ApiDoc.kt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package com.cubetiqs.web.controller
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Controller
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
|
import org.springframework.web.servlet.view.RedirectView
|
||||||
|
import springfox.documentation.annotations.ApiIgnore
|
||||||
|
|
||||||
|
@ApiIgnore
|
||||||
|
@Controller
|
||||||
|
class ApiDoc {
|
||||||
|
@GetMapping(value = [ "/api-doc", "/api-docs"])
|
||||||
|
fun redirect(): RedirectView {
|
||||||
|
return RedirectView("/swagger-ui/")
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.cubetiqs.web.controller
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus
|
||||||
|
import org.springframework.http.ResponseEntity
|
||||||
|
|
||||||
|
interface BaseController {
|
||||||
|
fun response(
|
||||||
|
data: Any?,
|
||||||
|
status: HttpStatus = HttpStatus.OK,
|
||||||
|
): ResponseEntity<Any?> {
|
||||||
|
return ResponseEntity.status(status).body(data)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.cubetiqs.web.controller
|
||||||
|
|
||||||
|
import com.cubetiqs.web.util.RouteConstants
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.boot.info.BuildProperties
|
||||||
|
import org.springframework.core.env.Environment
|
||||||
|
import org.springframework.http.ResponseEntity
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
import org.springframework.web.bind.annotation.RestController
|
||||||
|
import springfox.documentation.annotations.ApiIgnore
|
||||||
|
|
||||||
|
@ApiIgnore
|
||||||
|
@RestController
|
||||||
|
@RequestMapping(RouteConstants.INDEX)
|
||||||
|
class IndexController @Autowired constructor(
|
||||||
|
private val buildProperties: BuildProperties,
|
||||||
|
private val environment: Environment,
|
||||||
|
) : BaseController {
|
||||||
|
@GetMapping
|
||||||
|
fun index(): ResponseEntity<Any?> {
|
||||||
|
val view = mutableMapOf<String, Any?>()
|
||||||
|
view["info"] = "API Operation is running normally on ${environment.activeProfiles.joinToString(separator = ",")}"
|
||||||
|
view["name"] = buildProperties.name
|
||||||
|
view["service"] = buildProperties.artifact
|
||||||
|
view["version"] = buildProperties.version
|
||||||
|
view["date"] = buildProperties.time
|
||||||
|
view["commit"] = buildProperties["commitId"]
|
||||||
|
|
||||||
|
return response(view)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package com.cubetiqs.web.exception
|
||||||
|
|
||||||
|
open class BaseException : RuntimeException {
|
||||||
|
constructor() : super()
|
||||||
|
constructor(message: String?) : super(message)
|
||||||
|
constructor(message: String?, cause: Throwable?) : super(message, cause)
|
||||||
|
constructor(cause: Throwable?) : super(cause)
|
||||||
|
constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super(
|
||||||
|
message,
|
||||||
|
cause,
|
||||||
|
enableSuppression,
|
||||||
|
writableStackTrace
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.cubetiqs.web.infrastructure.component
|
||||||
|
|
||||||
|
interface BaseFunctionComponent<I, O> {
|
||||||
|
fun execute(input: I?): O?
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.cubetiqs.web.infrastructure.data
|
||||||
|
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
interface BaseEntity <ID : Serializable> : Serializable {
|
||||||
|
fun setId(id: ID)
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.cubetiqs.web.infrastructure.event
|
||||||
|
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
interface BaseEvent : Serializable
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.cubetiqs.web.infrastructure.listener
|
||||||
|
|
||||||
|
import com.cubetiqs.web.infrastructure.event.BaseEvent
|
||||||
|
|
||||||
|
interface BaseEventListener {
|
||||||
|
fun persist(event: BaseEvent) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
package com.cubetiqs.web.infrastructure.repository
|
||||||
|
|
||||||
|
interface BaseRepository
|
@ -0,0 +1,3 @@
|
|||||||
|
package com.cubetiqs.web.infrastructure.service
|
||||||
|
|
||||||
|
interface BaseService
|
5
api/src/main/kotlin/com/cubetiqs/web/model/ob/BaseOb.kt
Normal file
5
api/src/main/kotlin/com/cubetiqs/web/model/ob/BaseOb.kt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package com.cubetiqs.web.model.ob
|
||||||
|
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
interface BaseOb : Serializable
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.cubetiqs.web.model.request
|
||||||
|
|
||||||
|
import com.cubetiqs.web.model.ob.BaseOb
|
||||||
|
|
||||||
|
interface BaseResponseModel : BaseOb
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.cubetiqs.web.model.response
|
||||||
|
|
||||||
|
import com.cubetiqs.web.model.ob.BaseOb
|
||||||
|
|
||||||
|
interface BaseRequestModel : BaseOb
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.cubetiqs.web.modules
|
||||||
|
|
||||||
|
interface AppModule {
|
||||||
|
fun getModule(): Class<*>
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.cubetiqs.web.property
|
||||||
|
|
||||||
|
import com.cubetiqs.web.stereotype.FunctionComponent
|
||||||
|
import org.springframework.beans.factory.annotation.Value
|
||||||
|
|
||||||
|
@FunctionComponent
|
||||||
|
class AppProperties (
|
||||||
|
@Value("\${cubetiq.app.name:CUBETIQ API Service}")
|
||||||
|
val appName: String,
|
||||||
|
|
||||||
|
@Value("\${cubetiq.app.description:CUBETIQ APIs Documentation}")
|
||||||
|
val appDescription: String,
|
||||||
|
)
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.cubetiqs.web.stereotype
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Lazy
|
||||||
|
import org.springframework.core.annotation.AliasFor
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author sombochea <Sambo Chea>
|
||||||
|
* @email sombochea@cubetiqs.com
|
||||||
|
* @date 18/05/21
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
@Target(AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CLASS)
|
||||||
|
@Lazy(value = true)
|
||||||
|
@Component
|
||||||
|
annotation class FunctionComponent(
|
||||||
|
@get: AliasFor(annotation = Component::class)
|
||||||
|
val value: String = ""
|
||||||
|
)
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.cubetiqs.web.util
|
||||||
|
|
||||||
|
object RouteConstants {
|
||||||
|
const val INDEX = "/"
|
||||||
|
}
|
||||||
|
|
||||||
|
object AppConstants {
|
||||||
|
val BASE_PACKAGE_API_DOCS get() = "com.cubetiqs.web"
|
||||||
|
}
|
2
api/src/main/resources/application-dev.yml
Normal file
2
api/src/main/resources/application-dev.yml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
server:
|
||||||
|
port: 8080
|
16
api/src/main/resources/application.yml
Normal file
16
api/src/main/resources/application.yml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
spring:
|
||||||
|
profiles:
|
||||||
|
active: ${APP_PROFILE:dev}
|
||||||
|
application:
|
||||||
|
name: cubetiq-api-service
|
||||||
|
|
||||||
|
cubetiq:
|
||||||
|
app:
|
||||||
|
data-dir: ${APP_DATA_DIR:${user.home}/${spring.application.name}}
|
||||||
|
name: CUBETIQ API Service
|
||||||
|
description: CUBETIQ API's Documentation
|
||||||
|
|
||||||
|
logging:
|
||||||
|
file:
|
||||||
|
path: ${LOGGING_FILE_PATH:${cubetiq.app.data-dir}/logs/}
|
||||||
|
name: ${logging.file.path}/app.log
|
13
api/src/test/kotlin/com/cubetiqs/web/ApiApplicationTests.kt
Normal file
13
api/src/test/kotlin/com/cubetiqs/web/ApiApplicationTests.kt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package com.cubetiqs.web
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class ApiApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun contextLoads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1 +1,5 @@
|
|||||||
rootProject.name = "spring-kotlin-gradle-modules"
|
rootProject.name = "spring-web-modules"
|
||||||
|
|
||||||
|
include(
|
||||||
|
"api"
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user