Compare commits
42 Commits
feature/30
...
feature/33
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dbf8b046b0 | ||
|
|
6f183e38ec | ||
|
|
2c8b4c9a09 | ||
|
|
c0fcefa8c0 | ||
|
|
6036bd63ad | ||
|
|
cb5179abd7 | ||
|
|
9e376bfefb | ||
|
|
f4b11c755c | ||
|
|
af1a95b1c7 | ||
|
|
8cc64c879f | ||
|
|
e08c02a99a | ||
|
|
13566e1f86 | ||
|
|
0210499e66 | ||
|
|
42c8b3df14 | ||
|
|
54c4481031 | ||
|
|
2d142eb829 | ||
|
|
09b6beee53 | ||
|
|
a39084a11a | ||
|
|
1beaaad422 | ||
|
|
826cfb0eaa | ||
|
|
37169355da | ||
|
|
3e7b928d8f | ||
|
|
4585c797ca | ||
|
|
3a4f79fbdb | ||
|
|
88e162fa43 | ||
|
|
af67ae124b | ||
|
|
d3af3ac81b | ||
|
|
6601641875 | ||
|
|
8bae2da14a | ||
|
|
5445a54335 | ||
|
|
f4951990cd | ||
|
|
15744f1a9a | ||
|
|
b814a782b8 | ||
|
|
83239c39ec | ||
|
|
35d951a92d | ||
|
|
826badd638 | ||
|
|
8b7a39aea9 | ||
|
|
3e7b225778 | ||
|
|
833cc25c4a | ||
|
|
45e99554d4 | ||
|
|
504430bcd1 | ||
|
|
c5dfa90ab3 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -24,6 +24,7 @@ bin/
|
|||||||
out/
|
out/
|
||||||
!**/src/main/**/out/
|
!**/src/main/**/out/
|
||||||
!**/src/test/**/out/
|
!**/src/test/**/out/
|
||||||
|
lib/
|
||||||
|
|
||||||
### NetBeans ###
|
### NetBeans ###
|
||||||
/nbproject/private/
|
/nbproject/private/
|
||||||
|
|||||||
38
Jenkinsfile-service
Normal file
38
Jenkinsfile-service
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage('Init') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
sh 'whoami'
|
||||||
|
sh 'printenv'
|
||||||
|
|
||||||
|
FLYWAY_CONFIG = '/home/ec2-user/flyway/flyway.conf'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('DB Migrate') {
|
||||||
|
steps {
|
||||||
|
flywayrunner installationName: 'flywaytool-jenkins',
|
||||||
|
flywayCommand: 'info migrate validate',
|
||||||
|
commandLineArgs: "-configFiles=${FLYWAY_CONFIG}",
|
||||||
|
credentialsId: 'ecb29499-7272-4e8b-b3ab-a7a3ab7eafab',
|
||||||
|
locations: "filesystem:${WORKSPACE}/db/migration"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Test') {
|
||||||
|
steps {
|
||||||
|
sh './gradlew clean :dongne-service-api:test'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Build') {
|
||||||
|
steps {
|
||||||
|
sh './gradlew clean :dongne-service-api:build -x test'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
README.md
16
README.md
@@ -6,10 +6,18 @@
|
|||||||
<br>
|
<br>
|
||||||
|
|
||||||
## Specification
|
## Specification
|
||||||
- java 17
|
- Lang
|
||||||
- kotlin 1.6.21
|
- java 17
|
||||||
- Spring Boot 2.7.0
|
- kotlin 1.6.21
|
||||||
- MySQL 8.0.21
|
- Framework
|
||||||
|
- Spring Boot 2.7.0
|
||||||
|
- DB
|
||||||
|
- MySQL 8.0.21
|
||||||
|
- Flyway(migration)
|
||||||
|
- CI/CD
|
||||||
|
- Jenkins
|
||||||
|
- Cloud Server
|
||||||
|
- AWS Lightsail(Amazon Linux2)
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,26 @@
|
|||||||
|
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
|
||||||
|
import org.gradle.api.tasks.testing.logging.TestLogEvent
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
import org.springframework.boot.gradle.tasks.bundling.BootJar
|
import org.springframework.boot.gradle.tasks.bundling.BootJar
|
||||||
|
import plugin.BuildLifecyclePlugin
|
||||||
plugins {
|
import task.test.TestContainer
|
||||||
id(Plugins.Spring.boot).version(Version.Spring.boot)
|
import task.test.TestLoggingUtils
|
||||||
id(Plugins.Spring.dependencyManagement).version(Version.Spring.dependencyManagement).apply(false)
|
import task.test.TestSummary
|
||||||
kotlin(Plugins.Kotlin.jvm).version(Version.kotlin)
|
|
||||||
kotlin(Plugins.Kotlin.pluginSpring).version(Version.kotlin).apply(false)
|
|
||||||
kotlin(Plugins.Kotlin.pluginJpa).version(Version.kotlin).apply(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
val bootJar: BootJar by tasks
|
val bootJar: BootJar by tasks
|
||||||
bootJar.enabled = false
|
bootJar.enabled = false
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id(Plugins.Spring.BOOT).version(Version.Spring.BOOT)
|
||||||
|
id(Plugins.Spring.DEPENDENCY_MANAGEMENT).version(Version.Spring.DEPENDENCY_MANAGEMENT).apply(false)
|
||||||
|
kotlin(Plugins.Kotlin.JVM).version(Version.KOTLIN)
|
||||||
|
kotlin(Plugins.Kotlin.PLUGIN_SPRING).version(Version.KOTLIN).apply(false)
|
||||||
|
kotlin(Plugins.Kotlin.PLUGIN_JPA).version(Version.KOTLIN).apply(false)
|
||||||
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
group = "io.beaniejoy.dongecafe"
|
group = "io.beaniejoy.dongecafe"
|
||||||
version = Version.projectVersion
|
version = Version.PROJECT_VERSION
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
@@ -24,15 +30,18 @@ allprojects {
|
|||||||
subprojects {
|
subprojects {
|
||||||
apply {
|
apply {
|
||||||
plugin(Plugins.java)
|
plugin(Plugins.java)
|
||||||
plugin(Plugins.Spring.dependencyManagement)
|
plugin(Plugins.Spring.DEPENDENCY_MANAGEMENT)
|
||||||
plugin(Plugins.Spring.boot)
|
plugin(Plugins.Spring.BOOT)
|
||||||
|
|
||||||
plugin(Plugins.Kotlin.KOTLIN)
|
plugin(Plugins.Kotlin.KOTLIN)
|
||||||
plugin(Plugins.Kotlin.kotlinSpring)
|
plugin(Plugins.Kotlin.KOTLIN_SPRING)
|
||||||
plugin(Plugins.Kotlin.kotlinJpa)
|
plugin(Plugins.Kotlin.KOTLIN_JPA)
|
||||||
}
|
}
|
||||||
|
|
||||||
java.sourceCompatibility = JavaVersion.VERSION_17
|
java.apply {
|
||||||
|
sourceCompatibility = Version.JAVA
|
||||||
|
targetCompatibility = Version.JAVA
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// Spring Boot Project
|
// Spring Boot Project
|
||||||
@@ -52,9 +61,9 @@ subprojects {
|
|||||||
runtimeOnly("com.h2database:h2") // H2
|
runtimeOnly("com.h2database:h2") // H2
|
||||||
|
|
||||||
// JWT
|
// JWT
|
||||||
implementation("io.jsonwebtoken:jjwt-api:${Version.Deps.Jwt}")
|
implementation("io.jsonwebtoken:jjwt-api:${Version.Deps.JWT}")
|
||||||
runtimeOnly("io.jsonwebtoken:jjwt-impl:${Version.Deps.Jwt}")
|
runtimeOnly("io.jsonwebtoken:jjwt-impl:${Version.Deps.JWT}")
|
||||||
runtimeOnly("io.jsonwebtoken:jjwt-jackson:${Version.Deps.Jwt}")
|
runtimeOnly("io.jsonwebtoken:jjwt-jackson:${Version.Deps.JWT}")
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
implementation("io.github.microutils:kotlin-logging:${Version.Deps.KOTLIN_LOGGING}")
|
implementation("io.github.microutils:kotlin-logging:${Version.Deps.KOTLIN_LOGGING}")
|
||||||
@@ -65,14 +74,54 @@ subprojects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<KotlinCompile> {
|
tasks.withType<KotlinCompile> {
|
||||||
println("### Configuring $name in project ${project.name} ###")
|
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
freeCompilerArgs = listOf("-Xjsr305=strict")
|
freeCompilerArgs = listOf("-Xjsr305=strict")
|
||||||
jvmTarget = JavaVersion.VERSION_17.toString()
|
jvmTarget = Version.JAVA.toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for logging when build finished
|
||||||
|
apply<BuildLifecyclePlugin>()
|
||||||
|
|
||||||
|
// gradle test logging
|
||||||
tasks.withType<Test> {
|
tasks.withType<Test> {
|
||||||
useJUnitPlatform()
|
useJUnitPlatform()
|
||||||
|
|
||||||
|
testLogging {
|
||||||
|
events = setOf(
|
||||||
|
TestLogEvent.FAILED,
|
||||||
|
TestLogEvent.SKIPPED,
|
||||||
|
TestLogEvent.STANDARD_ERROR
|
||||||
|
)
|
||||||
|
|
||||||
|
exceptionFormat = TestExceptionFormat.FULL
|
||||||
|
showExceptions = true
|
||||||
|
showCauses = true
|
||||||
|
showStackTraces = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignoreFailures = true
|
||||||
|
|
||||||
|
addTestListener(object : TestListener {
|
||||||
|
override fun beforeSuite(desc: TestDescriptor) {}
|
||||||
|
// handling after all test finished
|
||||||
|
override fun afterSuite(desc: TestDescriptor, result: TestResult) {
|
||||||
|
if (desc.parent != null) return
|
||||||
|
|
||||||
|
val summary = TestSummary(
|
||||||
|
projectName = project.name,
|
||||||
|
taskName = name,
|
||||||
|
result = result
|
||||||
|
)
|
||||||
|
|
||||||
|
TestContainer.testResults = summary
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun beforeTest(desc: TestDescriptor) {}
|
||||||
|
// handling after each test finished
|
||||||
|
override fun afterTest(desc: TestDescriptor, result: TestResult) {
|
||||||
|
TestLoggingUtils.printEachResult(desc, result)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,4 +4,4 @@ plugins {
|
|||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
@@ -2,18 +2,18 @@ object Plugins {
|
|||||||
const val java = "java"
|
const val java = "java"
|
||||||
|
|
||||||
object Spring {
|
object Spring {
|
||||||
const val boot = "org.springframework.boot"
|
const val BOOT = "org.springframework.boot"
|
||||||
const val dependencyManagement = "io.spring.dependency-management"
|
const val DEPENDENCY_MANAGEMENT = "io.spring.dependency-management"
|
||||||
}
|
}
|
||||||
|
|
||||||
object Kotlin {
|
object Kotlin {
|
||||||
const val KOTLIN = "kotlin"
|
const val KOTLIN = "kotlin"
|
||||||
const val kotlinSpring = "kotlin-spring"
|
const val KOTLIN_SPRING = "kotlin-spring"
|
||||||
const val kotlinJpa = "kotlin-jpa"
|
const val KOTLIN_JPA = "kotlin-jpa"
|
||||||
|
|
||||||
const val jvm = "jvm"
|
const val JVM = "jvm"
|
||||||
const val pluginSpring = "plugin.spring"
|
const val PLUGIN_SPRING = "plugin.spring"
|
||||||
const val pluginJpa = "plugin.jpa"
|
const val PLUGIN_JPA = "plugin.jpa"
|
||||||
}
|
}
|
||||||
|
|
||||||
object FlywayDB {
|
object FlywayDB {
|
||||||
|
|||||||
@@ -1,15 +1,19 @@
|
|||||||
|
import org.gradle.api.JavaVersion
|
||||||
|
|
||||||
object Version {
|
object Version {
|
||||||
const val projectVersion = "0.0.1-SNAPSHOT"
|
const val PROJECT_VERSION = "0.0.1-SNAPSHOT"
|
||||||
const val kotlin = "1.6.21"
|
const val KOTLIN = "1.6.21"
|
||||||
|
|
||||||
|
val JAVA = JavaVersion.VERSION_17
|
||||||
|
|
||||||
object Spring {
|
object Spring {
|
||||||
const val boot = "2.7.0"
|
const val BOOT = "2.7.0"
|
||||||
const val dependencyManagement = "1.0.11.RELEASE"
|
const val DEPENDENCY_MANAGEMENT = "1.0.11.RELEASE"
|
||||||
}
|
}
|
||||||
|
|
||||||
object Deps {
|
object Deps {
|
||||||
const val KOTLIN_LOGGING = "3.0.4"
|
const val KOTLIN_LOGGING = "3.0.4"
|
||||||
const val Jwt = "0.11.5"
|
const val JWT = "0.11.5"
|
||||||
}
|
}
|
||||||
|
|
||||||
object FlywayDB {
|
object FlywayDB {
|
||||||
|
|||||||
23
buildSrc/src/main/kotlin/plugin/BuildLifecyclePlugin.kt
Normal file
23
buildSrc/src/main/kotlin/plugin/BuildLifecyclePlugin.kt
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package plugin
|
||||||
|
|
||||||
|
import org.gradle.api.Plugin
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.internal.build.event.BuildEventListenerRegistryInternal
|
||||||
|
import org.gradle.invocation.DefaultGradle
|
||||||
|
|
||||||
|
class BuildLifecyclePlugin : Plugin<Project> {
|
||||||
|
override fun apply(project: Project) {
|
||||||
|
val gradle = project.gradle
|
||||||
|
|
||||||
|
val services = (gradle as DefaultGradle).services
|
||||||
|
val registry = services[BuildEventListenerRegistryInternal::class.java]
|
||||||
|
|
||||||
|
val operationService = gradle.sharedServices.registerIfAbsent("operationService", BuildOperationService::class.java) {
|
||||||
|
gradle.taskGraph.whenReady {
|
||||||
|
parameters.lastTaskPath = this.allTasks.last().path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
registry.subscribe(operationService)
|
||||||
|
}
|
||||||
|
}
|
||||||
26
buildSrc/src/main/kotlin/plugin/BuildOperationService.kt
Normal file
26
buildSrc/src/main/kotlin/plugin/BuildOperationService.kt
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package plugin
|
||||||
|
|
||||||
|
import org.gradle.api.services.BuildService
|
||||||
|
import org.gradle.api.services.BuildServiceParameters
|
||||||
|
import org.gradle.tooling.events.FinishEvent
|
||||||
|
import org.gradle.tooling.events.OperationCompletionListener
|
||||||
|
import org.gradle.tooling.events.task.TaskFinishEvent
|
||||||
|
import task.test.TestContainer
|
||||||
|
import task.test.TestLoggingUtils
|
||||||
|
|
||||||
|
abstract class BuildOperationService : BuildService<BuildOperationService.Params>, OperationCompletionListener {
|
||||||
|
interface Params : BuildServiceParameters {
|
||||||
|
var lastTaskPath: String
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFinish(event: FinishEvent?) {
|
||||||
|
if (event == null || event !is TaskFinishEvent) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.descriptor.taskPath == parameters.lastTaskPath) {
|
||||||
|
TestLoggingUtils.printTotalResult(TestContainer.testResults)
|
||||||
|
TestContainer.testResults = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
buildSrc/src/main/kotlin/task/test/TestContainer.kt
Normal file
8
buildSrc/src/main/kotlin/task/test/TestContainer.kt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
package task.test
|
||||||
|
|
||||||
|
class TestContainer {
|
||||||
|
companion object {
|
||||||
|
var testResults: TestSummary? = null
|
||||||
|
const val colorMode: Boolean = false
|
||||||
|
}
|
||||||
|
}
|
||||||
55
buildSrc/src/main/kotlin/task/test/TestLoggingUtils.kt
Normal file
55
buildSrc/src/main/kotlin/task/test/TestLoggingUtils.kt
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
package task.test
|
||||||
|
|
||||||
|
import org.gradle.api.tasks.testing.TestDescriptor
|
||||||
|
import org.gradle.api.tasks.testing.TestResult
|
||||||
|
|
||||||
|
class TestLoggingUtils {
|
||||||
|
companion object {
|
||||||
|
const val ANSI_RESET = "\u001B[0m"
|
||||||
|
const val ANSI_GREEN = "\u001B[32m"
|
||||||
|
const val ANSI_RED = "\u001B[31m"
|
||||||
|
|
||||||
|
fun printTotalResult(summary: TestSummary?) {
|
||||||
|
if (summary == null) return
|
||||||
|
|
||||||
|
val maxLength = summary.maxWidth()
|
||||||
|
|
||||||
|
println(
|
||||||
|
"""
|
||||||
|
|┌${"─".repeat(maxLength)}┐
|
||||||
|
|${
|
||||||
|
summary.toLogList().joinToString("│\n│", "│", "│") {
|
||||||
|
val coloredResult = colorResultType(summary.result.resultType)
|
||||||
|
"$it${" ".repeat(maxLength - it.length)}"
|
||||||
|
.replace(
|
||||||
|
oldValue = coloredResult.first.toString(),
|
||||||
|
newValue = coloredResult.second
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|└${"─".repeat(maxLength)}┘
|
||||||
|
""".trimMargin()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun printEachResult(desc: TestDescriptor, result: TestResult) {
|
||||||
|
println("[${desc.className}] ${desc.displayName} >> result: ${colorResultType(result.resultType).second}")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun colorResultType(resultType: TestResult.ResultType): Pair<TestResult.ResultType, String> {
|
||||||
|
if (TestContainer.colorMode.not()) {
|
||||||
|
return resultType to "${resultType}"
|
||||||
|
}
|
||||||
|
|
||||||
|
val color = when (resultType) {
|
||||||
|
TestResult.ResultType.SUCCESS -> ANSI_GREEN
|
||||||
|
TestResult.ResultType.FAILURE -> ANSI_RED
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultType to if (color.isNotEmpty()) {
|
||||||
|
"${color}${resultType}$ANSI_RESET"
|
||||||
|
} else "${resultType}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
buildSrc/src/main/kotlin/task/test/TestSummary.kt
Normal file
20
buildSrc/src/main/kotlin/task/test/TestSummary.kt
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package task.test
|
||||||
|
|
||||||
|
import org.gradle.api.tasks.testing.TestResult
|
||||||
|
|
||||||
|
data class TestSummary(
|
||||||
|
val projectName: String? = null,
|
||||||
|
val taskName: String? = null,
|
||||||
|
val result: TestResult
|
||||||
|
) {
|
||||||
|
fun maxWidth(): Int {
|
||||||
|
return toLogList().maxByOrNull { it.length }?.length ?: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fun toLogList(): List<String> {
|
||||||
|
return listOf(
|
||||||
|
"${projectName}:${taskName} Test result: ${result.resultType}",
|
||||||
|
"Test summary: ${result.testCount} tests, ${result.successfulTestCount} succeeded, ${result.failedTestCount} failed, ${result.skippedTestCount} skipped"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,8 +19,7 @@ flyway {
|
|||||||
baselineDescription = "Start Flyway Migration!"
|
baselineDescription = "Start Flyway Migration!"
|
||||||
baselineOnMigrate = true
|
baselineOnMigrate = true
|
||||||
baselineVersion = "000"
|
baselineVersion = "000"
|
||||||
locations = arrayOf("filesystem:./migration", "filesystem:./seed")
|
configFiles = arrayOf(System.getProperty("config") ?: "flyway.conf")
|
||||||
configFiles = arrayOf("conf/flyway.conf")
|
|
||||||
cleanDisabled = false // activate flywayClean
|
cleanDisabled = false // activate flywayClean
|
||||||
ignoreMigrationPatterns = arrayOf("*:pending") // ignore validating pending(대기) state
|
ignoreMigrationPatterns = arrayOf("*:pending") // ignore validating pending(대기) state
|
||||||
}
|
}
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
flyway.url=jdbc:mysql://localhost:3306/dongne?autoreconnect=true&characterEncoding=utf8&serverTimezone=Asia/Seoul
|
|
||||||
flyway.user=root
|
|
||||||
flyway.password=beaniejoy
|
|
||||||
flyway.driver=com.mysql.cj.jdbc.Driver
|
|
||||||
10
db/flyway.conf
Normal file
10
db/flyway.conf
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
flyway.url=jdbc:mysql://localhost:3306/dongne?autoreconnect=true&characterEncoding=utf8&serverTimezone=Asia/Seoul
|
||||||
|
flyway.user=root
|
||||||
|
flyway.password=beaniejoy
|
||||||
|
flyway.driver=com.mysql.cj.jdbc.Driver
|
||||||
|
flyway.locations=filesystem:db/migration,db/seed
|
||||||
|
|
||||||
|
flyway.baselineOnMigrate=true
|
||||||
|
flyway.baselineVersion=000
|
||||||
|
# flyway.ignoreMigrationPatterns=*:pending
|
||||||
|
flyway.cleanDisabled=false
|
||||||
@@ -6,8 +6,8 @@ CREATE TABLE `cafe` (
|
|||||||
`total_rate` float NOT NULL COMMENT '카페 종합 평가 점수',
|
`total_rate` float NOT NULL COMMENT '카페 종합 평가 점수',
|
||||||
`description` varchar(255) COMMENT '카페 상세설명',
|
`description` varchar(255) COMMENT '카페 상세설명',
|
||||||
`created_at` datetime NOT NULL COMMENT '카페 등록날짜',
|
`created_at` datetime NOT NULL COMMENT '카페 등록날짜',
|
||||||
`created_by` varchar(20) NOT NULL COMMENT '카페 등록자',
|
`created_by` varchar(320) NOT NULL COMMENT '카페 등록자',
|
||||||
`updated_at` datetime NULL COMMENT '카페 변경날짜',
|
`updated_at` datetime NULL COMMENT '카페 변경날짜',
|
||||||
`updated_by` varchar(20) NULL COMMENT '카페 변경자',
|
`updated_by` varchar(320) NULL COMMENT '카페 변경자',
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||||
@@ -3,9 +3,9 @@ CREATE TABLE `cafe_menu` (
|
|||||||
`name` varchar(50) NOT NULL COMMENT '카페 메뉴명',
|
`name` varchar(50) NOT NULL COMMENT '카페 메뉴명',
|
||||||
`price` decimal(10, 2) NOT NULL COMMENT '메뉴 가격',
|
`price` decimal(10, 2) NOT NULL COMMENT '메뉴 가격',
|
||||||
`created_at` datetime NOT NULL COMMENT '메뉴 등록날짜',
|
`created_at` datetime NOT NULL COMMENT '메뉴 등록날짜',
|
||||||
`created_by` varchar(20) NOT NULL COMMENT '메뉴 등록자',
|
`created_by` varchar(320) NOT NULL COMMENT '메뉴 등록자',
|
||||||
`updated_at` datetime COMMENT '메뉴 변경날짜',
|
`updated_at` datetime COMMENT '메뉴 변경날짜',
|
||||||
`updated_by` varchar(20) NULL COMMENT '메뉴 변경자',
|
`updated_by` varchar(320) NULL COMMENT '메뉴 변경자',
|
||||||
`cafe_id` bigint unsigned NOT NULL COMMENT '연관된 카페 ID',
|
`cafe_id` bigint unsigned NOT NULL COMMENT '연관된 카페 ID',
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
KEY `cafe_id` (`cafe_id`),
|
KEY `cafe_id` (`cafe_id`),
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ CREATE TABLE `cafe_image` (
|
|||||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '카페 이미지 ID',
|
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '카페 이미지 ID',
|
||||||
`img_url` varchar(255) NOT NULL COMMENT '이미지 경로',
|
`img_url` varchar(255) NOT NULL COMMENT '이미지 경로',
|
||||||
`created_at` datetime NOT NULL COMMENT '이미지 등록날짜',
|
`created_at` datetime NOT NULL COMMENT '이미지 등록날짜',
|
||||||
`created_by` varchar(20) NOT NULL COMMENT '이미지 등록자',
|
`created_by` varchar(320) NOT NULL COMMENT '이미지 등록자',
|
||||||
`updated_at` datetime COMMENT '이미지 변경날짜',
|
`updated_at` datetime COMMENT '이미지 변경날짜',
|
||||||
`updated_by` varchar(20) NULL COMMENT '이미지 변경자',
|
`updated_by` varchar(320) NULL COMMENT '이미지 변경자',
|
||||||
`cafe_id` bigint unsigned NOT NULL COMMENT '연관된 카페 ID',
|
`cafe_id` bigint unsigned NOT NULL COMMENT '연관된 카페 ID',
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
KEY `cafe_id` (`cafe_id`),
|
KEY `cafe_id` (`cafe_id`),
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ CREATE TABLE `menu_option`(
|
|||||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '옵션 ID',
|
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '옵션 ID',
|
||||||
`title` varchar(50) NOT NULL COMMENT '메뉴 옵션 이름',
|
`title` varchar(50) NOT NULL COMMENT '메뉴 옵션 이름',
|
||||||
`created_at` datetime NOT NULL COMMENT '옵션 등록날짜',
|
`created_at` datetime NOT NULL COMMENT '옵션 등록날짜',
|
||||||
`created_by` varchar(20) NOT NULL COMMENT '옵션 등록자',
|
`created_by` varchar(320) NOT NULL COMMENT '옵션 등록자',
|
||||||
`updated_at` datetime COMMENT '옵션 변경날짜',
|
`updated_at` datetime COMMENT '옵션 변경날짜',
|
||||||
`updated_by` varchar(20) NULL COMMENT '옵션 변경자',
|
`updated_by` varchar(320) NULL COMMENT '옵션 변경자',
|
||||||
`menu_id` bigint unsigned NOT NULL COMMENT '연관된 카페 메뉴 ID',
|
`menu_id` bigint unsigned NOT NULL COMMENT '연관된 카페 메뉴 ID',
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
KEY `menu_id` (`menu_id`),
|
KEY `menu_id` (`menu_id`),
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ CREATE TABLE `option_detail` (
|
|||||||
`name` varchar(50) NOT NULL COMMENT '옵션 상세명',
|
`name` varchar(50) NOT NULL COMMENT '옵션 상세명',
|
||||||
`extra_price` decimal(10, 2) NOT NULL COMMENT '옵션 추가 요금',
|
`extra_price` decimal(10, 2) NOT NULL COMMENT '옵션 추가 요금',
|
||||||
`created_at` datetime NOT NULL COMMENT '옵션 상세 등록날짜',
|
`created_at` datetime NOT NULL COMMENT '옵션 상세 등록날짜',
|
||||||
`created_by` varchar(20) NOT NULL COMMENT '옵션 상세 등록자',
|
`created_by` varchar(320) NOT NULL COMMENT '옵션 상세 등록자',
|
||||||
`updated_at` datetime COMMENT '옵션 상세 변경날짜',
|
`updated_at` datetime COMMENT '옵션 상세 변경날짜',
|
||||||
`updated_by` varchar(20) NULL COMMENT '옵션 상세 변경자',
|
`updated_by` varchar(320) NULL COMMENT '옵션 상세 변경자',
|
||||||
`option_id` bigint unsigned NOT NULL COMMENT '연관된 옵션 ID',
|
`option_id` bigint unsigned NOT NULL COMMENT '연관된 옵션 ID',
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
KEY `option_id` (`option_id`),
|
KEY `option_id` (`option_id`),
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ CREATE TABLE `member` (
|
|||||||
`role_type` varchar(20) COMMENT '회원 권한',
|
`role_type` varchar(20) COMMENT '회원 권한',
|
||||||
`activated` tinyint NOT NULL COMMENT '계정 활성화 여부',
|
`activated` tinyint NOT NULL COMMENT '계정 활성화 여부',
|
||||||
`created_at` datetime NOT NULL COMMENT '회원 등록날짜',
|
`created_at` datetime NOT NULL COMMENT '회원 등록날짜',
|
||||||
`created_by` varchar(20) NOT NULL COMMENT '회원 등록자',
|
`created_by` varchar(320) NOT NULL COMMENT '회원 등록자',
|
||||||
`updated_at` datetime NULL COMMENT '회원 변경날짜',
|
`updated_at` datetime NULL COMMENT '회원 변경날짜',
|
||||||
`updated_by` varchar(20) NULL COMMENT '회원 변경자',
|
`updated_by` varchar(320) NULL COMMENT '회원 변경자',
|
||||||
PRIMARY KEY (`member_id`)
|
PRIMARY KEY (`member_id`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package io.beaniejoy.dongnecafe.common.config
|
|
||||||
|
|
||||||
import org.springframework.context.annotation.Configuration
|
|
||||||
import org.springframework.data.jpa.repository.config.EnableJpaAuditing
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@EnableJpaAuditing
|
|
||||||
class AuditingConfig
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
package io.beaniejoy.dongnecafe.common.entity
|
|
||||||
|
|
||||||
import org.springframework.data.domain.AuditorAware
|
|
||||||
import org.springframework.stereotype.Component
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
@Component
|
|
||||||
class BaseEntityAuditorAware: AuditorAware<String> {
|
|
||||||
override fun getCurrentAuditor(): Optional<String> {
|
|
||||||
return Optional.of("system")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package io.beaniejoy.dongnecafe.common.config
|
||||||
|
|
||||||
|
import io.beaniejoy.dongnecafe.security.getAuthPrincipal
|
||||||
|
import mu.KLogging
|
||||||
|
import org.springframework.context.annotation.Bean
|
||||||
|
import org.springframework.context.annotation.Configuration
|
||||||
|
import org.springframework.data.domain.AuditorAware
|
||||||
|
import org.springframework.data.jpa.repository.config.EnableJpaAuditing
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableJpaAuditing
|
||||||
|
class AuditingConfig {
|
||||||
|
companion object: KLogging() {
|
||||||
|
const val SYSTEM = "system"
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
fun auditorProvider(): AuditorAware<String> {
|
||||||
|
return AuditorAware<String> {
|
||||||
|
Optional.of(SecurityContextHolder.getContext().authentication?.getAuthPrincipal() ?: SYSTEM)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package io.beaniejoy.dongnecafe.common.entity
|
||||||
|
|
||||||
|
import org.springframework.data.annotation.CreatedBy
|
||||||
|
import org.springframework.data.annotation.LastModifiedBy
|
||||||
|
import org.springframework.data.jpa.domain.support.AuditingEntityListener
|
||||||
|
import javax.persistence.Column
|
||||||
|
import javax.persistence.EntityListeners
|
||||||
|
import javax.persistence.MappedSuperclass
|
||||||
|
|
||||||
|
@MappedSuperclass
|
||||||
|
@EntityListeners(AuditingEntityListener::class)
|
||||||
|
abstract class BaseEntity protected constructor() : BaseTimeEntity() {
|
||||||
|
@CreatedBy
|
||||||
|
@Column(updatable = false)
|
||||||
|
lateinit var createdBy: String
|
||||||
|
protected set
|
||||||
|
|
||||||
|
@LastModifiedBy
|
||||||
|
lateinit var updatedBy: String
|
||||||
|
protected set
|
||||||
|
}
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
package io.beaniejoy.dongnecafe.common
|
package io.beaniejoy.dongnecafe.common.entity
|
||||||
|
|
||||||
import org.springframework.data.annotation.CreatedBy
|
|
||||||
import org.springframework.data.annotation.CreatedDate
|
import org.springframework.data.annotation.CreatedDate
|
||||||
import org.springframework.data.annotation.LastModifiedBy
|
|
||||||
import org.springframework.data.annotation.LastModifiedDate
|
import org.springframework.data.annotation.LastModifiedDate
|
||||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener
|
import org.springframework.data.jpa.domain.support.AuditingEntityListener
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
|
import javax.persistence.Column
|
||||||
import javax.persistence.EntityListeners
|
import javax.persistence.EntityListeners
|
||||||
import javax.persistence.MappedSuperclass
|
import javax.persistence.MappedSuperclass
|
||||||
|
|
||||||
@@ -13,18 +12,11 @@ import javax.persistence.MappedSuperclass
|
|||||||
@EntityListeners(AuditingEntityListener::class)
|
@EntityListeners(AuditingEntityListener::class)
|
||||||
abstract class BaseTimeEntity protected constructor() {
|
abstract class BaseTimeEntity protected constructor() {
|
||||||
@CreatedDate
|
@CreatedDate
|
||||||
var createdAt: LocalDateTime = LocalDateTime.now()
|
@Column(updatable = false)
|
||||||
protected set
|
lateinit var createdAt: LocalDateTime
|
||||||
|
|
||||||
@CreatedBy
|
|
||||||
var createdBy: String = ""
|
|
||||||
protected set
|
protected set
|
||||||
|
|
||||||
@LastModifiedDate
|
@LastModifiedDate
|
||||||
var updatedAt: LocalDateTime? = null
|
lateinit var updatedAt: LocalDateTime
|
||||||
protected set
|
|
||||||
|
|
||||||
@LastModifiedBy
|
|
||||||
var updatedBy: String? = null
|
|
||||||
protected set
|
protected set
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package io.beaniejoy.dongnecafe.domain.cafe.entity
|
package io.beaniejoy.dongnecafe.domain.cafe.entity
|
||||||
|
|
||||||
import io.beaniejoy.dongnecafe.common.BaseTimeEntity
|
import io.beaniejoy.dongnecafe.common.entity.BaseEntity
|
||||||
import io.beaniejoy.dongnecafe.domain.cafe.model.request.CafeMenuRegisterRequest
|
import io.beaniejoy.dongnecafe.domain.cafe.model.request.CafeMenuRegisterRequest
|
||||||
import javax.persistence.*
|
import javax.persistence.*
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ class Cafe protected constructor(
|
|||||||
address: String,
|
address: String,
|
||||||
phoneNumber: String,
|
phoneNumber: String,
|
||||||
description: String,
|
description: String,
|
||||||
) : BaseTimeEntity() {
|
) : BaseEntity() {
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
@Column(name = "cafe_id", nullable = false)
|
@Column(name = "cafe_id", nullable = false)
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package io.beaniejoy.dongnecafe.domain.cafe.entity
|
package io.beaniejoy.dongnecafe.domain.cafe.entity
|
||||||
|
|
||||||
import io.beaniejoy.dongnecafe.common.BaseTimeEntity
|
import io.beaniejoy.dongnecafe.common.entity.BaseEntity
|
||||||
import javax.persistence.*
|
import javax.persistence.*
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "cafe_image")
|
@Table(name = "cafe_image")
|
||||||
class CafeImage(
|
class CafeImage protected constructor(
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
@Column(name = "cafe_image_id", nullable = false)
|
@Column(name = "cafe_image_id", nullable = false)
|
||||||
@@ -17,4 +17,4 @@ class CafeImage(
|
|||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "cafe_id", nullable = false)
|
@JoinColumn(name = "cafe_id", nullable = false)
|
||||||
val cafe: Cafe
|
val cafe: Cafe
|
||||||
) : BaseTimeEntity()
|
) : BaseEntity()
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package io.beaniejoy.dongnecafe.domain.cafe.entity
|
package io.beaniejoy.dongnecafe.domain.cafe.entity
|
||||||
|
|
||||||
import io.beaniejoy.dongnecafe.common.BaseTimeEntity
|
import io.beaniejoy.dongnecafe.common.entity.BaseEntity
|
||||||
import io.beaniejoy.dongnecafe.domain.cafe.model.request.MenuOptionRegisterRequest
|
import io.beaniejoy.dongnecafe.domain.cafe.model.request.MenuOptionRegisterRequest
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import javax.persistence.*
|
import javax.persistence.*
|
||||||
@@ -10,7 +10,7 @@ import javax.persistence.*
|
|||||||
class CafeMenu protected constructor(
|
class CafeMenu protected constructor(
|
||||||
name: String,
|
name: String,
|
||||||
price: BigDecimal,
|
price: BigDecimal,
|
||||||
) : BaseTimeEntity() {
|
) : BaseEntity() {
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
@Column(name = "cafe_menu_id", nullable = false)
|
@Column(name = "cafe_menu_id", nullable = false)
|
||||||
@@ -33,7 +33,11 @@ class CafeMenu protected constructor(
|
|||||||
val menuOptionList: MutableList<MenuOption> = arrayListOf()
|
val menuOptionList: MutableList<MenuOption> = arrayListOf()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun createCafeMenu(name: String, price: BigDecimal, menuOptionRequestList: List<MenuOptionRegisterRequest>): CafeMenu {
|
fun createCafeMenu(
|
||||||
|
name: String,
|
||||||
|
price: BigDecimal,
|
||||||
|
menuOptionRequestList: List<MenuOptionRegisterRequest>
|
||||||
|
): CafeMenu {
|
||||||
val menuOptionEntityList = menuOptionRequestList.map { menuOptionRequestDto ->
|
val menuOptionEntityList = menuOptionRequestList.map { menuOptionRequestDto ->
|
||||||
MenuOption.createMenuOption(
|
MenuOption.createMenuOption(
|
||||||
title = menuOptionRequestDto.title,
|
title = menuOptionRequestDto.title,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package io.beaniejoy.dongnecafe.domain.cafe.entity
|
package io.beaniejoy.dongnecafe.domain.cafe.entity
|
||||||
|
|
||||||
import io.beaniejoy.dongnecafe.common.BaseTimeEntity
|
import io.beaniejoy.dongnecafe.common.entity.BaseEntity
|
||||||
import io.beaniejoy.dongnecafe.domain.cafe.model.request.OptionDetailRegisterRequest
|
import io.beaniejoy.dongnecafe.domain.cafe.model.request.OptionDetailRegisterRequest
|
||||||
import javax.persistence.*
|
import javax.persistence.*
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@ import javax.persistence.*
|
|||||||
@Table(name = "menu_option")
|
@Table(name = "menu_option")
|
||||||
class MenuOption protected constructor(
|
class MenuOption protected constructor(
|
||||||
title: String
|
title: String
|
||||||
) : BaseTimeEntity() {
|
) : BaseEntity() {
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
@Column(name = "menu_option_id", nullable = false)
|
@Column(name = "menu_option_id", nullable = false)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package io.beaniejoy.dongnecafe.domain.cafe.entity
|
package io.beaniejoy.dongnecafe.domain.cafe.entity
|
||||||
|
|
||||||
import io.beaniejoy.dongnecafe.common.BaseTimeEntity
|
import io.beaniejoy.dongnecafe.common.entity.BaseEntity
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import javax.persistence.*
|
import javax.persistence.*
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@ import javax.persistence.*
|
|||||||
class OptionDetail protected constructor(
|
class OptionDetail protected constructor(
|
||||||
name: String,
|
name: String,
|
||||||
extraPrice: BigDecimal
|
extraPrice: BigDecimal
|
||||||
) : BaseTimeEntity() {
|
) : BaseEntity() {
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
@Column(name = "option_detail_id", nullable = false)
|
@Column(name = "option_detail_id", nullable = false)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package io.beaniejoy.dongnecafe.domain.member.entity
|
package io.beaniejoy.dongnecafe.domain.member.entity
|
||||||
|
|
||||||
import io.beaniejoy.dongnecafe.common.BaseTimeEntity
|
import io.beaniejoy.dongnecafe.common.entity.BaseEntity
|
||||||
import io.beaniejoy.dongnecafe.domain.member.constant.RoleType
|
import io.beaniejoy.dongnecafe.domain.member.constant.RoleType
|
||||||
import javax.persistence.*
|
import javax.persistence.*
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ class Member(
|
|||||||
password: String,
|
password: String,
|
||||||
address: String,
|
address: String,
|
||||||
phoneNumber: String
|
phoneNumber: String
|
||||||
): BaseTimeEntity() {
|
) : BaseEntity() {
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
@Column(name = "member_id", nullable = false)
|
@Column(name = "member_id", nullable = false)
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package io.beaniejoy.dongnecafe.security
|
||||||
|
|
||||||
|
import io.beaniejoy.dongnecafe.security.constant.SecurityConstant.ANONYMOUS_USER
|
||||||
|
import io.beaniejoy.dongnecafe.security.constant.SecurityConstant.ROLE_ANONYMOUS
|
||||||
|
import org.springframework.security.core.Authentication
|
||||||
|
|
||||||
|
fun Authentication.getAuthPrincipal() : String? {
|
||||||
|
if (this.isAnonymous()) return null
|
||||||
|
|
||||||
|
return this.principal.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Authentication.isAnonymous(): Boolean {
|
||||||
|
return this.principal == ANONYMOUS_USER || this.authorities.any { it.authority == ROLE_ANONYMOUS }
|
||||||
|
}
|
||||||
@@ -3,4 +3,7 @@ package io.beaniejoy.dongnecafe.security.constant
|
|||||||
object SecurityConstant {
|
object SecurityConstant {
|
||||||
const val BEARER = "Bearer"
|
const val BEARER = "Bearer"
|
||||||
const val WHITESPACE = " "
|
const val WHITESPACE = " "
|
||||||
|
|
||||||
|
const val ANONYMOUS_USER = "anonymousUser"
|
||||||
|
const val ROLE_ANONYMOUS = "ROLE_ANONYMOUS"
|
||||||
}
|
}
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package io.beaniejoy.dongnecafe.common.config
|
|
||||||
|
|
||||||
import org.springframework.context.annotation.Configuration
|
|
||||||
import org.springframework.data.jpa.repository.config.EnableJpaAuditing
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@EnableJpaAuditing
|
|
||||||
class AuditingConfig
|
|
||||||
@@ -21,10 +21,10 @@ class SecurityConfig {
|
|||||||
@Bean
|
@Bean
|
||||||
fun filterChain(http: HttpSecurity): SecurityFilterChain {
|
fun filterChain(http: HttpSecurity): SecurityFilterChain {
|
||||||
return http
|
return http
|
||||||
|
// only api 방식 인증 & 인가 적용 위해 csrf & formLogin 비활성화
|
||||||
.csrf().disable()
|
.csrf().disable()
|
||||||
.formLogin().disable()
|
.formLogin().disable()
|
||||||
|
|
||||||
// FIXME 임시 permitAll 설정
|
|
||||||
.authorizeRequests()
|
.authorizeRequests()
|
||||||
.anyRequest().authenticated()
|
.anyRequest().authenticated()
|
||||||
|
|
||||||
@@ -43,6 +43,7 @@ class SecurityConfig {
|
|||||||
.jwtTokenUtils(jwtTokenUtils)
|
.jwtTokenUtils(jwtTokenUtils)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Security Filter 미적용 자원 설정
|
||||||
@Bean
|
@Bean
|
||||||
fun webSecurityCustomizer(): WebSecurityCustomizer {
|
fun webSecurityCustomizer(): WebSecurityCustomizer {
|
||||||
return WebSecurityCustomizer { web ->
|
return WebSecurityCustomizer { web ->
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
package io.beaniejoy.dongnecafe.common.entity
|
|
||||||
|
|
||||||
import org.springframework.data.domain.AuditorAware
|
|
||||||
import org.springframework.stereotype.Component
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
@Component
|
|
||||||
class BaseEntityAuditorAware: AuditorAware<String> {
|
|
||||||
override fun getCurrentAuditor(): Optional<String> {
|
|
||||||
// TODO 추후 사용자 로그인 기능 추가되면 실제 등록한 사용자를 DB에 저장하는 방향으로 수정
|
|
||||||
return Optional.of("system")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -24,9 +24,11 @@ class JwtAuthenticationFilter(
|
|||||||
val httpRequest = request as HttpServletRequest
|
val httpRequest = request as HttpServletRequest
|
||||||
log.info { "[JwtAuthenticationFilter][${request.dispatcherType}] uri: ${request.requestURI}" }
|
log.info { "[JwtAuthenticationFilter][${request.dispatcherType}] uri: ${request.requestURI}" }
|
||||||
|
|
||||||
|
// 인증 헤더에 토큰값 없는 경우 pass
|
||||||
getAccessToken(httpRequest)?.let {
|
getAccessToken(httpRequest)?.let {
|
||||||
jwtTokenUtils.getAuthentication(it)
|
jwtTokenUtils.getAuthentication(it)
|
||||||
}?.also {
|
}?.also {
|
||||||
|
// 유효한 인증 토큰 존재하는 경우 SecurityContext 토큰값 저장
|
||||||
SecurityContextHolder.getContext().authentication = it
|
SecurityContextHolder.getContext().authentication = it
|
||||||
log.info { "Valid Access Token [${it.name}]" }
|
log.info { "Valid Access Token [${it.name}]" }
|
||||||
}
|
}
|
||||||
@@ -34,6 +36,10 @@ class JwtAuthenticationFilter(
|
|||||||
chain.doFilter(request, response)
|
chain.doFilter(request, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 인증 토큰 획득
|
||||||
|
* Authorization : Bearer [AUTH_TOKEN]
|
||||||
|
*/
|
||||||
private fun getAccessToken(request: HttpServletRequest): String? {
|
private fun getAccessToken(request: HttpServletRequest): String? {
|
||||||
val bearer = request.getHeader(HttpHeaders.AUTHORIZATION)
|
val bearer = request.getHeader(HttpHeaders.AUTHORIZATION)
|
||||||
?: return null
|
?: return null
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package io.beaniejoy.dongnecafe.domain.cafe.repository
|
package io.beaniejoy.dongnecafe.domain.cafe.repository
|
||||||
|
|
||||||
import io.beaniejoy.dongnecafe.common.config.AuditingConfig
|
import io.beaniejoy.dongnecafe.common.config.AuditingConfig
|
||||||
import io.beaniejoy.dongnecafe.common.entity.BaseEntityAuditorAware
|
|
||||||
import io.beaniejoy.dongnecafe.domain.cafe.entity.Cafe
|
import io.beaniejoy.dongnecafe.domain.cafe.entity.Cafe
|
||||||
import io.beaniejoy.dongnecafe.domain.cafe.utils.CafeTestUtils
|
import io.beaniejoy.dongnecafe.domain.cafe.utils.CafeTestUtils
|
||||||
import mu.KLogging
|
import mu.KLogging
|
||||||
@@ -17,7 +16,6 @@ import org.springframework.data.repository.findByIdOrNull
|
|||||||
@DataJpaTest(
|
@DataJpaTest(
|
||||||
includeFilters = [
|
includeFilters = [
|
||||||
ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = [AuditingConfig::class]),
|
ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = [AuditingConfig::class]),
|
||||||
ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = [BaseEntityAuditorAware::class])
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
internal class CafeRepositoryTest {
|
internal class CafeRepositoryTest {
|
||||||
|
|||||||
@@ -87,13 +87,13 @@ internal class CafeServiceTest {
|
|||||||
fun update_cafe_test() {
|
fun update_cafe_test() {
|
||||||
// given
|
// given
|
||||||
val (name, address, phoneNumber, description, cafeMenuList) = CafeTestUtils.createCafeRegisterRequest()
|
val (name, address, phoneNumber, description, cafeMenuList) = CafeTestUtils.createCafeRegisterRequest()
|
||||||
val cafe = Cafe.createCafe(
|
// val cafe = Cafe.createCafe(
|
||||||
name = name!!,
|
// name = name!!,
|
||||||
address = address!!,
|
// address = address!!,
|
||||||
phoneNumber = phoneNumber!!,
|
// phoneNumber = phoneNumber!!,
|
||||||
description = description!!,
|
// description = description!!,
|
||||||
cafeMenuRequestList = cafeMenuList
|
// cafeMenuRequestList = cafeMenuList
|
||||||
)
|
// )
|
||||||
val cafeId = 50L
|
val cafeId = 50L
|
||||||
|
|
||||||
// TODO 'findByIdOrNull'은 kotlin test 라이브러리 필요한 듯
|
// TODO 'findByIdOrNull'은 kotlin test 라이브러리 필요한 듯
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
spring:
|
spring:
|
||||||
flyway:
|
|
||||||
enabled: false
|
|
||||||
jpa:
|
jpa:
|
||||||
properties:
|
properties:
|
||||||
hibernate:
|
hibernate:
|
||||||
@@ -9,7 +7,7 @@ spring:
|
|||||||
|
|
||||||
logging:
|
logging:
|
||||||
level:
|
level:
|
||||||
org.hibernate.SQL: debug
|
org.hibernate.SQL: info # ionShutdownHook logging issue (in 'DEBUG' level)
|
||||||
org.hibernate.type: trace # 실제 sql 쿼리의 parameter 값을 확인하고자 함
|
org.hibernate.type: trace # 실제 sql 쿼리의 parameter 값을 확인하고자 함
|
||||||
|
|
||||||
jwt:
|
jwt:
|
||||||
|
|||||||
10
script/db_migration.sh
Normal file
10
script/db_migration.sh
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "================ 1. Flyway Info ================"
|
||||||
|
./gradlew :db:flywayInfo -Dconfig=$1
|
||||||
|
|
||||||
|
echo "================ 2. Flyway Validate ============"
|
||||||
|
./gradlew :db:flywayValidate -Dconfig=$1
|
||||||
|
|
||||||
|
echo "================ 3. Flyway Migrate ============="
|
||||||
|
./gradlew :db:flywayMigrate -Dconfig=$1
|
||||||
Reference in New Issue
Block a user