Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: flyway 적용 #42

Merged
merged 7 commits into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 69 additions & 34 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
buildscript {
dependencies {
classpath("${libs.testcontainers.postgresql.get()}")
classpath("${libs.flyway.database.postgresql.get()}")
}
}

plugins {
java
id("org.springframework.boot") version "3.3.1"
id("io.spring.dependency-management") version "1.1.5"
id("com.diffplug.spotless") version "6.25.0"
alias(libs.plugins.spring.boot)
alias(libs.plugins.spring.dependency.management)
alias(libs.plugins.spotless)
alias(libs.plugins.flyway)
}

group = "com.dnd"
Expand All @@ -18,44 +26,33 @@ repositories {
}

dependencies {
implementation("org.springframework.boot:spring-boot-starter")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("me.paulschwarz:spring-dotenv:4.0.0")

// Web
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.4.0")
implementation(libs.bundles.spring.boot)
implementation(libs.dotenv)
implementation(libs.jetbrains.annotations)
implementation(libs.springdoc)

// JWT
implementation("io.jsonwebtoken:jjwt-api:0.12.6")
runtimeOnly("io.jsonwebtoken:jjwt-impl:0.12.6")
runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.12.6")
implementation(libs.jjwt.api)
runtimeOnly(libs.jjwt.impl)
runtimeOnly(libs.jjwt.jackson)

// Database
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.postgresql:postgresql:42.7.3")
runtimeOnly ("org.postgresql:postgresql")
implementation ("org.hibernate:hibernate-spatial:6.4.0.Final")
implementation(libs.postgresql)
runtimeOnly(libs.postgresql)
implementation(libs.hibernate.spatial)

implementation(libs.flyway.core)
runtimeOnly(libs.flyway.database.postgresql)

// Lombok
implementation("org.projectlombok:lombok:1.18.34")
annotationProcessor("org.projectlombok:lombok:1.18.34")
testCompileOnly("org.projectlombok:lombok:1.18.34")
testAnnotationProcessor("org.projectlombok:lombok:1.18.34")

// testcontainers
testImplementation("org.springframework.boot:spring-boot-testcontainers")
testImplementation("org.testcontainers:testcontainers:1.20.0")
testImplementation("org.testcontainers:junit-jupiter:1.20.0")
testImplementation("org.testcontainers:jdbc:1.20.0")
testImplementation("org.testcontainers:postgresql:1.20.0")

testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.security:spring-security-test")
testImplementation("org.springframework.boot:spring-boot-devtools")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
implementation(libs.lombok)
annotationProcessor(libs.lombok)
testCompileOnly(libs.lombok)
testAnnotationProcessor(libs.lombok)

testImplementation(libs.bundles.spring.boot.test)
testImplementation(libs.bundles.testcontainers)
testRuntimeOnly(libs.junit.platform.launcher)
}

tasks.withType<Test> {
Expand Down Expand Up @@ -120,3 +117,41 @@ tasks.register("projectTest") {
dependsOn("compileJava")
dependsOn("test")
}

tasks.named<org.flywaydb.gradle.task.FlywayMigrateTask>("flywayMigrate") {
usesService(dbContainerProvider)
locations = arrayOf("filesystem:src/main/resources/db/migration")
inputs.files(fileTree("src/main/resources/db/migration"))

doFirst {
val dbContainer = dbContainerProvider.get().container()
url = dbContainer.jdbcUrl
user = dbContainer.username
password = dbContainer.password
}
doLast {
if (dbContainerProvider.isPresent) {
dbContainerProvider.get().close()
}
}
}

// Here we register service for providing our database during the build.
val dbContainerProvider: Provider<PostgresService> = project.gradle
.sharedServices
.registerIfAbsent("postgres", PostgresService::class.java) {}

// Build service for providing database container.
abstract class PostgresService : BuildService<BuildServiceParameters.None>, AutoCloseable {
private val container = org.testcontainers.containers.PostgreSQLContainer<Nothing>(
org.testcontainers.utility.DockerImageName.parse(
"imresamu/postgis:16-3.4-alpine"
).asCompatibleSubstituteFor("postgres")
).apply {
start()
}

override fun close() = container.stop()

fun container() = container
}
65 changes: 65 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
[versions]
spring-boot = "3.3.2"
dependency-management = "1.1.5"
spotless = "6.25.0"
postgresql = "42.7.3"
testcontainers = "1.20.1"
flyway = "10.17.0"
jjwt = "0.12.6"

[libraries]
spring-boot-starter = { group = "org.springframework.boot", name = "spring-boot-starter", version.ref = "spring-boot" }
spring-boot-starter-web = { group = "org.springframework.boot", name = "spring-boot-starter-web", version.ref = "spring-boot" }
spring-boot-starter-security = { group = "org.springframework.boot", name = "spring-boot-starter-security", version.ref = "spring-boot" }
spring-boot-starter-validation = { group = "org.springframework.boot", name = "spring-boot-starter-validation", version.ref = "spring-boot" }
spring-boot-starter-actuator = { group = "org.springframework.boot", name = "spring-boot-starter-actuator", version.ref = "spring-boot" }
spring-boot-starter-data-jpa = { group = "org.springframework.boot", name = "spring-boot-starter-data-jpa", version.ref = "spring-boot" }
spring-boot-devtools = { group = "org.springframework.boot", name = "spring-boot-devtools", version.ref = "spring-boot" }
spring-boot-starter-test = { group = "org.springframework.boot", name = "spring-boot-starter-test", version.ref = "spring-boot" }
spring-boot-testcontainers = { group = "org.springframework.boot", name = "spring-boot-testcontainers", version.ref = "spring-boot" }

lombok = { group = "org.projectlombok", name = "lombok", version = "1.18.34" }
dotenv = { group = "me.paulschwarz", name = "spring-dotenv", version = "4.0.0" }
jetbrains-annotations = { group = "org.jetbrains", name = "annotations", version = "24.1.0" }
jjwt-api = { group = "io.jsonwebtoken", name = "jjwt-api", version.ref = "jjwt" }
jjwt-impl = { group = "io.jsonwebtoken", name = "jjwt-impl", version.ref = "jjwt" }
jjwt-jackson = { group = "io.jsonwebtoken", name = "jjwt-jackson", version.ref = "jjwt" }
postgresql = { group = "org.postgresql", name = "postgresql", version.ref = "postgresql" }
hibernate-spatial = { group = "org.hibernate", name = "hibernate-spatial", version = "6.5.1.Final" }
flyway-core = { group = "org.flywaydb", name = "flyway-core", version.ref = "flyway" }
flyway-database-postgresql = { group = "org.flywaydb", name = "flyway-database-postgresql", version.ref = "flyway" }
springdoc = { group = "org.springdoc", name = "springdoc-openapi-starter-webmvc-ui", version = "2.4.0" }
testcontainers = { group = "org.testcontainers", name = "testcontainers", version.ref = "testcontainers" }
testcontainers-junit-jupiter = { group = "org.testcontainers", name = "junit-jupiter", version.ref = "testcontainers" }
testcontainers-jdbc = { group = "org.testcontainers", name = "jdbc", version.ref = "testcontainers" }
testcontainers-postgresql = { group = "org.testcontainers", name = "postgresql", version.ref = "testcontainers" }
junit-platform-launcher = { group = "org.junit.platform", name = "junit-platform-launcher" }

[bundles]
spring-boot = [
"spring-boot-starter",
"spring-boot-starter-web",
"spring-boot-starter-security",
"spring-boot-starter-validation",
"spring-boot-starter-actuator",
"spring-boot-starter-data-jpa",
]

spring-boot-test = [
"spring-boot-devtools",
"spring-boot-starter-test",
]

testcontainers = [
"spring-boot-testcontainers",
"testcontainers",
"testcontainers-junit-jupiter",
"testcontainers-postgresql",
"testcontainers-jdbc"
]

[plugins]
spring-boot = { id = "org.springframework.boot", version.ref = "spring-boot" }
spring-dependency-management = { id = "io.spring.dependency-management", version.ref = "dependency-management" }
spotless = { id = "com.diffplug.spotless", version.ref = "spotless" }
flyway = { id = "org.flywaydb.flyway", version.ref = "flyway" }
2 changes: 1 addition & 1 deletion src/main/java/com/dnd/runus/domain/level/Level.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package com.dnd.runus.domain.level;

public record Level(long levelId, int requiredExp) {}
public record Level(long levelId, int expRangeStart, int expRangeEnd) {}
5 changes: 1 addition & 4 deletions src/main/java/com/dnd/runus/domain/member/Member.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.dnd.runus.domain.member;

import com.dnd.runus.domain.badge.Badge;
import com.dnd.runus.domain.level.Level;
import com.dnd.runus.global.constant.MemberRole;
import lombok.Builder;

Expand All @@ -15,6 +14,4 @@ public record Member(
MemberRole role,
String nickname,
Badge mainBadge,
int weightKg,
Level level,
int currentExp) {}
int weightKg) {}
3 changes: 3 additions & 0 deletions src/main/java/com/dnd/runus/domain/member/MemberLevel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.dnd.runus.domain.member;

public record MemberLevel(long levelId, int exp) {}
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@ public Optional<SocialProfile> findBySocialTypeAndOauthId(SocialType socialType,

@Override
public SocialProfile save(SocialProfile socialProfile) {
SocialProfileEntity entity = jpaSocialProfileRepository.save(SocialProfileEntity.of(
socialProfile.socialType(),
socialProfile.oauthId(),
socialProfile.oauthEmail(),
socialProfile.memberId()));
return entity.toDomain();
return jpaSocialProfileRepository
.save(SocialProfileEntity.of(
socialProfile.socialType(),
socialProfile.oauthId(),
socialProfile.oauthEmail(),
socialProfile.memberId()))
.toDomain();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.dnd.runus.domain.badge.Badge;
import com.dnd.runus.domain.common.BaseTimeEntity;
import com.dnd.runus.domain.level.Level;
import com.dnd.runus.domain.member.Member;
import com.dnd.runus.global.constant.MemberRole;
import jakarta.persistence.*;
Expand Down Expand Up @@ -46,10 +45,10 @@ public static MemberEntity from(Member member) {
}

public Member toDomain() {
return toDomain(null, null, -1);
return toDomain(null);
}

public Member toDomain(Badge mainBadge, Level level, int currentExp) {
public Member toDomain(Badge mainBadge) {
return Member.builder()
.memberId(id)
.createdAt(getCreatedAt())
Expand All @@ -58,8 +57,6 @@ public Member toDomain(Badge mainBadge, Level level, int currentExp) {
.nickname(nickname)
.weightKg(weightKg)
.mainBadge(mainBadge)
.level(level)
.currentExp(currentExp)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package com.dnd.runus.infrastructure.persistence.jpa.member.entity;

import com.dnd.runus.domain.common.BaseTimeEntity;
import com.dnd.runus.domain.level.Level;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import com.dnd.runus.domain.member.Member;
import com.dnd.runus.domain.member.MemberLevel;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.NoArgsConstructor;

import static jakarta.persistence.FetchType.LAZY;
import static lombok.AccessLevel.PROTECTED;

@Getter
Expand All @@ -21,23 +20,24 @@ public class MemberLevelEntity extends BaseTimeEntity {
private Long id;

@NotNull
private Long memberId;
@OneToOne(fetch = LAZY)
private MemberEntity member;

@NotNull
private Long levelId;

@NotNull
private Integer exp;

public static MemberLevelEntity of(Long memberId, Long levelId, Integer exp) {
public static MemberLevelEntity of(Member member, long levelId, int exp) {
MemberLevelEntity memberLevelEntity = new MemberLevelEntity();
memberLevelEntity.memberId = memberId;
memberLevelEntity.member = MemberEntity.from(member);
memberLevelEntity.levelId = levelId;
memberLevelEntity.exp = exp;
return memberLevelEntity;
}

public Level toDomain() {
return new Level(levelId, exp);
public MemberLevel toDomain() {
return new MemberLevel(levelId, exp);
}
}
6 changes: 1 addition & 5 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ spring:
ddl-auto: none
show-sql: true
open-in-view: false
defer-datasource-initialization: false

datasource:
driver-class-name: org.postgresql.Driver
Expand All @@ -30,10 +31,5 @@ oauth:
---
spring.config.activate.on-profile: local

spring:
jpa:
hibernate:
ddl-auto: update

---
spring.config.activate.on-profile: prod
Loading