From 5554d6aeb4d7c886c26bed72600eef6cfbc1919d Mon Sep 17 00:00:00 2001 From: SuHun <104614675+Suhun0331@users.noreply.github.com> Date: Wed, 30 Apr 2025 16:58:37 +0900 Subject: [PATCH 01/43] Create CI.yml --- .github/workflows/CI.yml | 67 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .github/workflows/CI.yml diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml new file mode 100644 index 0000000..87d5ecb --- /dev/null +++ b/.github/workflows/CI.yml @@ -0,0 +1,67 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. +# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle + +name: Java CI with Gradle + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + + # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies. + # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md + - name: Setup Gradle + uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0 + + - name: Build with Gradle Wrapper + run: ./gradlew build + + # NOTE: The Gradle Wrapper is the default and recommended way to run Gradle (https://docs.gradle.org/current/userguide/gradle_wrapper.html). + # If your project does not have the Gradle Wrapper configured, you can use the following configuration to run Gradle with a specified version. + # + # - name: Setup Gradle + # uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0 + # with: + # gradle-version: '8.9' + # + # - name: Build with Gradle 8.9 + # run: gradle build + + dependency-submission: + + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + + # Generates and submits a dependency graph, enabling Dependabot Alerts for all project dependencies. + # See: https://github.com/gradle/actions/blob/main/dependency-submission/README.md + - name: Generate and submit dependency graph + uses: gradle/actions/dependency-submission@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0 From 0d464aa833e7c0815f925c5245006c3bc0f82822 Mon Sep 17 00:00:00 2001 From: Suhun0331 Date: Wed, 30 Apr 2025 17:01:45 +0900 Subject: [PATCH 02/43] Feat : CI setting --- .github/workflows/CI.yml | 77 ++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 51 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 87d5ecb..67fa220 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -1,67 +1,42 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. -# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time -# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle - -name: Java CI with Gradle +name: CI FOR MVP on: push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] + branches-ignore: + - main + - develop jobs: - build: - + CI: + name: Continuous Integration runs-on: ubuntu-latest permissions: contents: read steps: - - uses: actions/checkout@v4 - - name: Set up JDK 17 - uses: actions/setup-java@v4 - with: - java-version: '17' - distribution: 'temurin' - - # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies. - # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md - - name: Setup Gradle - uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0 + - name: Checkout + uses: actions/checkout@v4 - - name: Build with Gradle Wrapper - run: ./gradlew build + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' - # NOTE: The Gradle Wrapper is the default and recommended way to run Gradle (https://docs.gradle.org/current/userguide/gradle_wrapper.html). - # If your project does not have the Gradle Wrapper configured, you can use the following configuration to run Gradle with a specified version. - # - # - name: Setup Gradle - # uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0 - # with: - # gradle-version: '8.9' - # - # - name: Build with Gradle 8.9 - # run: gradle build + - name: Setup MySQL + uses: mirromutth/mysql-action@v1.1 + with: + mysql database: 'testDB' + mysql user: 'test' + mysql password: 'testPW' - dependency-submission: + - name: Setup Gradle + uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 - runs-on: ubuntu-latest - permissions: - contents: write + - name: Get short SHA + id: slug + run: echo "sha7=$(echo ${GITHUB_SHA} | cut -c1-7)" >> $GITHUB_OUTPUT - steps: - - uses: actions/checkout@v4 - - name: Set up JDK 17 - uses: actions/setup-java@v4 - with: - java-version: '17' - distribution: 'temurin' + - name: Build with Gradle Wrapper + run: ./gradlew build - # Generates and submits a dependency graph, enabling Dependabot Alerts for all project dependencies. - # See: https://github.com/gradle/actions/blob/main/dependency-submission/README.md - - name: Generate and submit dependency graph - uses: gradle/actions/dependency-submission@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0 From 4079440180f91f1e0204955435b8c4d52a78b1a2 Mon Sep 17 00:00:00 2001 From: etoile0626 Date: Wed, 30 Apr 2025 17:08:39 +0900 Subject: [PATCH 03/43] Test --- src/main/java/com/quickpick/ureca/UrecaApplication.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/quickpick/ureca/UrecaApplication.java b/src/main/java/com/quickpick/ureca/UrecaApplication.java index 5911fa6..41112d2 100644 --- a/src/main/java/com/quickpick/ureca/UrecaApplication.java +++ b/src/main/java/com/quickpick/ureca/UrecaApplication.java @@ -11,3 +11,4 @@ public static void main(String[] args) { } } +//test \ No newline at end of file From 8d03ed42900ac908428fcbf59789ce374198f569 Mon Sep 17 00:00:00 2001 From: etoile0626 Date: Wed, 30 Apr 2025 17:10:54 +0900 Subject: [PATCH 04/43] issue test (#1) --- src/main/java/com/quickpick/ureca/UrecaApplication.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/quickpick/ureca/UrecaApplication.java b/src/main/java/com/quickpick/ureca/UrecaApplication.java index 41112d2..5911fa6 100644 --- a/src/main/java/com/quickpick/ureca/UrecaApplication.java +++ b/src/main/java/com/quickpick/ureca/UrecaApplication.java @@ -11,4 +11,3 @@ public static void main(String[] args) { } } -//test \ No newline at end of file From fe6888a75a90e7f26bd6c559d50c5b127f3430f4 Mon Sep 17 00:00:00 2001 From: Suhun0331 Date: Wed, 30 Apr 2025 17:11:25 +0900 Subject: [PATCH 05/43] Feat : add db info --- src/main/resources/application.properties | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4ab8d35..eabf1a0 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,18 @@ spring.application.name=ureca + +# spring jpa +spring.jpa.database=mysql +spring.jpa.show-sql=true +spring.jpa.properties.hibernate.format_sql=true +spring.datasource.url=jdbc:mysql://localhost:3306/testdb?characterEncoding=UTF-8&serverTimezone=Asia/Seoul +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver + +commit.hash=local +api.server.url=http://localhost:8080 + +spring.datasource.username=test +spring.datasource.password=testPW +spring.jpa.hibernate.ddl-auto=create + + + From 7fe683980ca2f6d33b96740bc8c8201c0dcbeeff Mon Sep 17 00:00:00 2001 From: Suhun0331 Date: Wed, 30 Apr 2025 17:12:54 +0900 Subject: [PATCH 06/43] Fix : fix ci error --- .github/workflows/CI.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 67fa220..10540c5 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -31,12 +31,14 @@ jobs: mysql password: 'testPW' - name: Setup Gradle - uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 + uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 - name: Get short SHA id: slug run: echo "sha7=$(echo ${GITHUB_SHA} | cut -c1-7)" >> $GITHUB_OUTPUT + - name: Grant execute permission for gradlew + run: chmod +x ./gradlew + - name: Build with Gradle Wrapper run: ./gradlew build - From 5a5f57ba81cd19d808c7a60802d2ae2872310d9b Mon Sep 17 00:00:00 2001 From: etoile0626 Date: Wed, 30 Apr 2025 17:08:39 +0900 Subject: [PATCH 07/43] Test --- src/main/java/com/quickpick/ureca/UrecaApplication.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/quickpick/ureca/UrecaApplication.java b/src/main/java/com/quickpick/ureca/UrecaApplication.java index 5911fa6..41112d2 100644 --- a/src/main/java/com/quickpick/ureca/UrecaApplication.java +++ b/src/main/java/com/quickpick/ureca/UrecaApplication.java @@ -11,3 +11,4 @@ public static void main(String[] args) { } } +//test \ No newline at end of file From fcaffd2c40cd649d92591e42ad85cbccda1e69d4 Mon Sep 17 00:00:00 2001 From: etoile0626 Date: Wed, 30 Apr 2025 17:10:54 +0900 Subject: [PATCH 08/43] issue test (#1) --- src/main/java/com/quickpick/ureca/UrecaApplication.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/quickpick/ureca/UrecaApplication.java b/src/main/java/com/quickpick/ureca/UrecaApplication.java index 41112d2..5911fa6 100644 --- a/src/main/java/com/quickpick/ureca/UrecaApplication.java +++ b/src/main/java/com/quickpick/ureca/UrecaApplication.java @@ -11,4 +11,3 @@ public static void main(String[] args) { } } -//test \ No newline at end of file From fd14f8ac66aabffdc4fe44c41739e3e0841ab24b Mon Sep 17 00:00:00 2001 From: Suhun0331 Date: Wed, 30 Apr 2025 17:25:17 +0900 Subject: [PATCH 09/43] Refactor : change CI range, delete DB id, pw --- .github/workflows/CI.yml | 6 +++--- src/main/resources/application.properties | 11 ++--------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 10540c5..4331c41 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -2,9 +2,9 @@ name: CI FOR MVP on: push: - branches-ignore: - - main - - develop +# branches-ignore: +# - main +# - develop jobs: CI: diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index eabf1a0..dc0c1db 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -7,12 +7,5 @@ spring.jpa.properties.hibernate.format_sql=true spring.datasource.url=jdbc:mysql://localhost:3306/testdb?characterEncoding=UTF-8&serverTimezone=Asia/Seoul spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver -commit.hash=local -api.server.url=http://localhost:8080 - -spring.datasource.username=test -spring.datasource.password=testPW -spring.jpa.hibernate.ddl-auto=create - - - +# spring data source +spring.jpa.hibernate.ddl-auto=create \ No newline at end of file From 1a2c7b34a3e3788dfc761c8957eed10f6e33d285 Mon Sep 17 00:00:00 2001 From: etoile0626 Date: Wed, 30 Apr 2025 22:12:49 +0900 Subject: [PATCH 10/43] =?UTF-8?q?user(=EC=97=B0=EA=B4=80=EA=B4=80=EA=B3=84?= =?UTF-8?q?=20=EB=AF=B8=EC=99=84=EC=84=B1),=20reserve=20=EA=B0=9D=EC=B2=B4?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + .../com/quickpick/ureca/UrecaApplication.java | 1 + .../reserve/controller/ReserveController.java | 4 ++ .../ureca/reserve/domain/Reserve.java | 35 +++++++++++++ .../reserve/repository/ReserveRepository.java | 4 ++ .../ureca/reserve/service/ReserveService.java | 4 ++ .../ureca/user/controller/UserController.java | 4 ++ .../com/quickpick/ureca/user/domain/User.java | 50 +++++++++++++++++++ .../ureca/user/repository/UserRepository.java | 4 ++ .../ureca/user/service/UserService.java | 4 ++ src/main/resources/application.properties | 11 ++-- 11 files changed, 115 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/quickpick/ureca/reserve/controller/ReserveController.java create mode 100644 src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java create mode 100644 src/main/java/com/quickpick/ureca/reserve/repository/ReserveRepository.java create mode 100644 src/main/java/com/quickpick/ureca/reserve/service/ReserveService.java create mode 100644 src/main/java/com/quickpick/ureca/user/controller/UserController.java create mode 100644 src/main/java/com/quickpick/ureca/user/domain/User.java create mode 100644 src/main/java/com/quickpick/ureca/user/repository/UserRepository.java create mode 100644 src/main/java/com/quickpick/ureca/user/service/UserService.java diff --git a/.gitignore b/.gitignore index c2065bc..4284c4a 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,5 @@ out/ ### VS Code ### .vscode/ + +**/src/main/resources/application_local.properties \ No newline at end of file diff --git a/src/main/java/com/quickpick/ureca/UrecaApplication.java b/src/main/java/com/quickpick/ureca/UrecaApplication.java index 5911fa6..c68d0ed 100644 --- a/src/main/java/com/quickpick/ureca/UrecaApplication.java +++ b/src/main/java/com/quickpick/ureca/UrecaApplication.java @@ -2,6 +2,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; @SpringBootApplication public class UrecaApplication { diff --git a/src/main/java/com/quickpick/ureca/reserve/controller/ReserveController.java b/src/main/java/com/quickpick/ureca/reserve/controller/ReserveController.java new file mode 100644 index 0000000..7b3818a --- /dev/null +++ b/src/main/java/com/quickpick/ureca/reserve/controller/ReserveController.java @@ -0,0 +1,4 @@ +package com.quickpick.ureca.reserve.controller; + +public class ReserveController { +} diff --git a/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java b/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java new file mode 100644 index 0000000..b8356e9 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java @@ -0,0 +1,35 @@ +package com.quickpick.ureca.reserve.domain; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; + +import java.time.LocalDateTime; + +@Table(name = "user") +@Entity +@Getter +@NoArgsConstructor +public class Reserve { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "reserve_id") + private Long reserveId; + + @Column(name = "user_id", nullable = false) + private String userId; + + @Column(nullable = false) + private String status; + + @CreatedDate + @Column(nullable = false) + private LocalDateTime created_at; + + @LastModifiedDate + @Column(nullable = false) + private LocalDateTime updated_at; +} diff --git a/src/main/java/com/quickpick/ureca/reserve/repository/ReserveRepository.java b/src/main/java/com/quickpick/ureca/reserve/repository/ReserveRepository.java new file mode 100644 index 0000000..d9dfba9 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/reserve/repository/ReserveRepository.java @@ -0,0 +1,4 @@ +package com.quickpick.ureca.reserve.repository; + +public class ReserveRepository { +} diff --git a/src/main/java/com/quickpick/ureca/reserve/service/ReserveService.java b/src/main/java/com/quickpick/ureca/reserve/service/ReserveService.java new file mode 100644 index 0000000..28c25c2 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/reserve/service/ReserveService.java @@ -0,0 +1,4 @@ +package com.quickpick.ureca.reserve.service; + +public class ReserveService { +} diff --git a/src/main/java/com/quickpick/ureca/user/controller/UserController.java b/src/main/java/com/quickpick/ureca/user/controller/UserController.java new file mode 100644 index 0000000..5ea1b6a --- /dev/null +++ b/src/main/java/com/quickpick/ureca/user/controller/UserController.java @@ -0,0 +1,4 @@ +package com.quickpick.ureca.user.controller; + +public class UserController { +} diff --git a/src/main/java/com/quickpick/ureca/user/domain/User.java b/src/main/java/com/quickpick/ureca/user/domain/User.java new file mode 100644 index 0000000..122ea72 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/user/domain/User.java @@ -0,0 +1,50 @@ +package com.quickpick.ureca.user.domain; + +import com.quickpick.ureca.reserve.domain.Reserve; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Table(name = "user") +@Entity +@Getter +@NoArgsConstructor +public class User { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "user_id") + private Long userId; + + @Column(nullable = false) + private String id; + + @Column(nullable = false) + private String password; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private String age; + + @Column(nullable = false) + private String gender; + + @CreatedDate + @Column(updatable = false) + private LocalDateTime created_at; + + @LastModifiedDate + private LocalDateTime updated_at; + + @OneToMany + @JoinColumn(name = "reserve_id") + private List reserveList = new ArrayList<>(); +} diff --git a/src/main/java/com/quickpick/ureca/user/repository/UserRepository.java b/src/main/java/com/quickpick/ureca/user/repository/UserRepository.java new file mode 100644 index 0000000..50abb0e --- /dev/null +++ b/src/main/java/com/quickpick/ureca/user/repository/UserRepository.java @@ -0,0 +1,4 @@ +package com.quickpick.ureca.user.repository; + +public class UserRepository { +} diff --git a/src/main/java/com/quickpick/ureca/user/service/UserService.java b/src/main/java/com/quickpick/ureca/user/service/UserService.java new file mode 100644 index 0000000..972e2b1 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/user/service/UserService.java @@ -0,0 +1,4 @@ +package com.quickpick.ureca.user.service; + +public class UserService { +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index eabf1a0..d94ccef 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -7,12 +7,7 @@ spring.jpa.properties.hibernate.format_sql=true spring.datasource.url=jdbc:mysql://localhost:3306/testdb?characterEncoding=UTF-8&serverTimezone=Asia/Seoul spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver -commit.hash=local -api.server.url=http://localhost:8080 - -spring.datasource.username=test -spring.datasource.password=testPW +# spring data source spring.jpa.hibernate.ddl-auto=create - - - +spring.datasource.username=root +spring.datasource.password=root \ No newline at end of file From e4239255612820e5f971cba30b34347462a63e5c Mon Sep 17 00:00:00 2001 From: etoile0626 Date: Wed, 30 Apr 2025 22:21:20 +0900 Subject: [PATCH 11/43] =?UTF-8?q?user,=20reserve=20=EA=B0=9D=EC=B2=B4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20(=EC=97=B0=EA=B4=80=20=EA=B4=80=EA=B3=84?= =?UTF-8?q?=20=EB=AF=B8=EC=99=84=EC=84=B1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../quickpick/ureca/reserve/domain/Reserve.java | 4 ++-- .../com/quickpick/ureca/user/domain/User.java | 15 ++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java b/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java index b8356e9..390e341 100644 --- a/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java +++ b/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java @@ -8,7 +8,7 @@ import java.time.LocalDateTime; -@Table(name = "user") +@Table @Entity @Getter @NoArgsConstructor @@ -22,7 +22,7 @@ public class Reserve { @Column(name = "user_id", nullable = false) private String userId; - @Column(nullable = false) + @Column(name = "status", nullable = false) private String status; @CreatedDate diff --git a/src/main/java/com/quickpick/ureca/user/domain/User.java b/src/main/java/com/quickpick/ureca/user/domain/User.java index 122ea72..619a9c4 100644 --- a/src/main/java/com/quickpick/ureca/user/domain/User.java +++ b/src/main/java/com/quickpick/ureca/user/domain/User.java @@ -11,7 +11,7 @@ import java.util.ArrayList; import java.util.List; -@Table(name = "user") +@Table @Entity @Getter @NoArgsConstructor @@ -22,19 +22,19 @@ public class User { @Column(name = "user_id") private Long userId; - @Column(nullable = false) + @Column(name = "id", nullable = false) private String id; - @Column(nullable = false) + @Column(name = "password", nullable = false) private String password; - @Column(nullable = false) + @Column(name = "name", nullable = false) private String name; - @Column(nullable = false) + @Column(name = "age", nullable = false) private String age; - @Column(nullable = false) + @Column(name = "gender", nullable = false) private String gender; @CreatedDate @@ -43,8 +43,9 @@ public class User { @LastModifiedDate private LocalDateTime updated_at; - +/* @OneToMany @JoinColumn(name = "reserve_id") private List reserveList = new ArrayList<>(); + */ } From 397459dfb6c29b1e0ea183ea20bfa15c6f0d0e81 Mon Sep 17 00:00:00 2001 From: etoile0626 Date: Wed, 30 Apr 2025 22:41:56 +0900 Subject: [PATCH 12/43] =?UTF-8?q?user,=20reserve=20=EA=B0=9D=EC=B2=B4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20(=EC=97=B0=EA=B4=80=20=EA=B4=80=EA=B3=84?= =?UTF-8?q?=20=EB=8B=A8=EB=B0=A9=ED=96=A5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/quickpick/ureca/UrecaApplication.java | 1 - .../quickpick/ureca/reserve/domain/Reserve.java | 8 +++++--- .../com/quickpick/ureca/user/domain/User.java | 16 ++++++---------- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/quickpick/ureca/UrecaApplication.java b/src/main/java/com/quickpick/ureca/UrecaApplication.java index c68d0ed..5911fa6 100644 --- a/src/main/java/com/quickpick/ureca/UrecaApplication.java +++ b/src/main/java/com/quickpick/ureca/UrecaApplication.java @@ -2,7 +2,6 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.PropertySource; @SpringBootApplication public class UrecaApplication { diff --git a/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java b/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java index 390e341..778c5a9 100644 --- a/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java +++ b/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java @@ -1,5 +1,6 @@ package com.quickpick.ureca.reserve.domain; +import com.quickpick.ureca.user.domain.User; import jakarta.persistence.*; import lombok.Getter; import lombok.NoArgsConstructor; @@ -19,10 +20,11 @@ public class Reserve { @Column(name = "reserve_id") private Long reserveId; - @Column(name = "user_id", nullable = false) - private String userId; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", nullable = false) + private User user; - @Column(name = "status", nullable = false) + @Column(nullable = false) private String status; @CreatedDate diff --git a/src/main/java/com/quickpick/ureca/user/domain/User.java b/src/main/java/com/quickpick/ureca/user/domain/User.java index 619a9c4..bb04fd7 100644 --- a/src/main/java/com/quickpick/ureca/user/domain/User.java +++ b/src/main/java/com/quickpick/ureca/user/domain/User.java @@ -22,19 +22,19 @@ public class User { @Column(name = "user_id") private Long userId; - @Column(name = "id", nullable = false) + @Column(nullable = false) private String id; - @Column(name = "password", nullable = false) + @Column(nullable = false) private String password; - @Column(name = "name", nullable = false) + @Column(nullable = false) private String name; - @Column(name = "age", nullable = false) + @Column(nullable = false) private String age; - @Column(name = "gender", nullable = false) + @Column(nullable = false) private String gender; @CreatedDate @@ -43,9 +43,5 @@ public class User { @LastModifiedDate private LocalDateTime updated_at; -/* - @OneToMany - @JoinColumn(name = "reserve_id") - private List reserveList = new ArrayList<>(); - */ + } From c96b0ba8670b39d098bfab821f778127959f9994 Mon Sep 17 00:00:00 2001 From: etoile0626 Date: Wed, 30 Apr 2025 23:00:53 +0900 Subject: [PATCH 13/43] Ignore application.properties --- src/main/resources/application.properties | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 src/main/resources/application.properties diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties deleted file mode 100644 index d94ccef..0000000 --- a/src/main/resources/application.properties +++ /dev/null @@ -1,13 +0,0 @@ -spring.application.name=ureca - -# spring jpa -spring.jpa.database=mysql -spring.jpa.show-sql=true -spring.jpa.properties.hibernate.format_sql=true -spring.datasource.url=jdbc:mysql://localhost:3306/testdb?characterEncoding=UTF-8&serverTimezone=Asia/Seoul -spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver - -# spring data source -spring.jpa.hibernate.ddl-auto=create -spring.datasource.username=root -spring.datasource.password=root \ No newline at end of file From 0a93661589a89dd6a38abaf67d06a0941ef7b9ee Mon Sep 17 00:00:00 2001 From: etoile0626 Date: Wed, 30 Apr 2025 23:06:15 +0900 Subject: [PATCH 14/43] test --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 4284c4a..39fb52a 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,4 @@ out/ ### VS Code ### .vscode/ -**/src/main/resources/application_local.properties \ No newline at end of file +/src/main/resources/application.properties \ No newline at end of file From 07f57f3e39f87419586a19863acdb4557f505a63 Mon Sep 17 00:00:00 2001 From: etoile0626 Date: Wed, 30 Apr 2025 23:10:12 +0900 Subject: [PATCH 15/43] =?UTF-8?q?user,=20reserve=20=EA=B0=9D=EC=B2=B4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20(=EC=97=B0=EA=B4=80=20=EA=B4=80=EA=B3=84?= =?UTF-8?q?=20=EB=8B=A8=EB=B0=A9=ED=96=A5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.properties | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 src/main/resources/application.properties diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties deleted file mode 100644 index d94ccef..0000000 --- a/src/main/resources/application.properties +++ /dev/null @@ -1,13 +0,0 @@ -spring.application.name=ureca - -# spring jpa -spring.jpa.database=mysql -spring.jpa.show-sql=true -spring.jpa.properties.hibernate.format_sql=true -spring.datasource.url=jdbc:mysql://localhost:3306/testdb?characterEncoding=UTF-8&serverTimezone=Asia/Seoul -spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver - -# spring data source -spring.jpa.hibernate.ddl-auto=create -spring.datasource.username=root -spring.datasource.password=root \ No newline at end of file From 7a5cce060f17a0d98a3ec9d1df31e923368757d7 Mon Sep 17 00:00:00 2001 From: ghdtmdalsda Date: Thu, 1 May 2025 01:30:22 +0900 Subject: [PATCH 16/43] =?UTF-8?q?feat:=20Ticket=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../quickpick/ureca/ticket/domain/Ticket.java | 46 +++++++++++++++++++ .../ticket/repository/TicketRepository.java | 7 +++ .../com/quickpick/ureca/user/domain/User.java | 9 ++++ 3 files changed, 62 insertions(+) create mode 100644 src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java create mode 100644 src/main/java/com/quickpick/ureca/ticket/repository/TicketRepository.java diff --git a/src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java b/src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java new file mode 100644 index 0000000..afa416c --- /dev/null +++ b/src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java @@ -0,0 +1,46 @@ +package com.quickpick.ureca.ticket.domain; + +import com.quickpick.ureca.user.domain.User; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Entity +@Table(name = "ticket") +@Getter +@NoArgsConstructor +public class Ticket { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "ticket_id") + private Long ticketId; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private int quantity; + + @Column(nullable = false) + private LocalDateTime startDate; + + @Column(nullable = false) + private LocalDateTime reserveDate; + + @CreatedDate + @Column(updatable = false) + private LocalDateTime createdAt; + + @LastModifiedDate + private LocalDateTime updatedAt; + + @ManyToMany(mappedBy = "tickets") + private List users = new ArrayList<>(); +} diff --git a/src/main/java/com/quickpick/ureca/ticket/repository/TicketRepository.java b/src/main/java/com/quickpick/ureca/ticket/repository/TicketRepository.java new file mode 100644 index 0000000..34b9f66 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/ticket/repository/TicketRepository.java @@ -0,0 +1,7 @@ +package com.quickpick.ureca.ticket.repository; + +import com.quickpick.ureca.ticket.domain.Ticket; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface TicketRepository extends JpaRepository { +} diff --git a/src/main/java/com/quickpick/ureca/user/domain/User.java b/src/main/java/com/quickpick/ureca/user/domain/User.java index bb04fd7..8716084 100644 --- a/src/main/java/com/quickpick/ureca/user/domain/User.java +++ b/src/main/java/com/quickpick/ureca/user/domain/User.java @@ -1,6 +1,7 @@ package com.quickpick.ureca.user.domain; import com.quickpick.ureca.reserve.domain.Reserve; +import com.quickpick.ureca.ticket.domain.Ticket; import jakarta.persistence.*; import lombok.Getter; import lombok.NoArgsConstructor; @@ -44,4 +45,12 @@ public class User { @LastModifiedDate private LocalDateTime updated_at; + @ManyToMany + @JoinTable( + name = "user_ticket", + joinColumns = @JoinColumn(name = "user_id"), + inverseJoinColumns = @JoinColumn(name = "ticket_id") + ) + private List tickets = new ArrayList<>(); + } From 7946e25ec948cb9398e12d313e707e234862e389 Mon Sep 17 00:00:00 2001 From: etoile0626 Date: Wed, 30 Apr 2025 22:12:49 +0900 Subject: [PATCH 17/43] =?UTF-8?q?user(=EC=97=B0=EA=B4=80=EA=B4=80=EA=B3=84?= =?UTF-8?q?=20=EB=AF=B8=EC=99=84=EC=84=B1),=20reserve=20=EA=B0=9D=EC=B2=B4?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=20(#1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + .../com/quickpick/ureca/UrecaApplication.java | 1 + .../reserve/controller/ReserveController.java | 4 ++ .../ureca/reserve/domain/Reserve.java | 35 +++++++++++++ .../reserve/repository/ReserveRepository.java | 4 ++ .../ureca/reserve/service/ReserveService.java | 4 ++ .../ureca/user/controller/UserController.java | 4 ++ .../com/quickpick/ureca/user/domain/User.java | 50 +++++++++++++++++++ .../ureca/user/repository/UserRepository.java | 4 ++ .../ureca/user/service/UserService.java | 4 ++ src/main/resources/application.properties | 11 ++-- 11 files changed, 115 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/quickpick/ureca/reserve/controller/ReserveController.java create mode 100644 src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java create mode 100644 src/main/java/com/quickpick/ureca/reserve/repository/ReserveRepository.java create mode 100644 src/main/java/com/quickpick/ureca/reserve/service/ReserveService.java create mode 100644 src/main/java/com/quickpick/ureca/user/controller/UserController.java create mode 100644 src/main/java/com/quickpick/ureca/user/domain/User.java create mode 100644 src/main/java/com/quickpick/ureca/user/repository/UserRepository.java create mode 100644 src/main/java/com/quickpick/ureca/user/service/UserService.java diff --git a/.gitignore b/.gitignore index c2065bc..4284c4a 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,5 @@ out/ ### VS Code ### .vscode/ + +**/src/main/resources/application_local.properties \ No newline at end of file diff --git a/src/main/java/com/quickpick/ureca/UrecaApplication.java b/src/main/java/com/quickpick/ureca/UrecaApplication.java index 5911fa6..c68d0ed 100644 --- a/src/main/java/com/quickpick/ureca/UrecaApplication.java +++ b/src/main/java/com/quickpick/ureca/UrecaApplication.java @@ -2,6 +2,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; @SpringBootApplication public class UrecaApplication { diff --git a/src/main/java/com/quickpick/ureca/reserve/controller/ReserveController.java b/src/main/java/com/quickpick/ureca/reserve/controller/ReserveController.java new file mode 100644 index 0000000..7b3818a --- /dev/null +++ b/src/main/java/com/quickpick/ureca/reserve/controller/ReserveController.java @@ -0,0 +1,4 @@ +package com.quickpick.ureca.reserve.controller; + +public class ReserveController { +} diff --git a/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java b/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java new file mode 100644 index 0000000..b8356e9 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java @@ -0,0 +1,35 @@ +package com.quickpick.ureca.reserve.domain; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; + +import java.time.LocalDateTime; + +@Table(name = "user") +@Entity +@Getter +@NoArgsConstructor +public class Reserve { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "reserve_id") + private Long reserveId; + + @Column(name = "user_id", nullable = false) + private String userId; + + @Column(nullable = false) + private String status; + + @CreatedDate + @Column(nullable = false) + private LocalDateTime created_at; + + @LastModifiedDate + @Column(nullable = false) + private LocalDateTime updated_at; +} diff --git a/src/main/java/com/quickpick/ureca/reserve/repository/ReserveRepository.java b/src/main/java/com/quickpick/ureca/reserve/repository/ReserveRepository.java new file mode 100644 index 0000000..d9dfba9 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/reserve/repository/ReserveRepository.java @@ -0,0 +1,4 @@ +package com.quickpick.ureca.reserve.repository; + +public class ReserveRepository { +} diff --git a/src/main/java/com/quickpick/ureca/reserve/service/ReserveService.java b/src/main/java/com/quickpick/ureca/reserve/service/ReserveService.java new file mode 100644 index 0000000..28c25c2 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/reserve/service/ReserveService.java @@ -0,0 +1,4 @@ +package com.quickpick.ureca.reserve.service; + +public class ReserveService { +} diff --git a/src/main/java/com/quickpick/ureca/user/controller/UserController.java b/src/main/java/com/quickpick/ureca/user/controller/UserController.java new file mode 100644 index 0000000..5ea1b6a --- /dev/null +++ b/src/main/java/com/quickpick/ureca/user/controller/UserController.java @@ -0,0 +1,4 @@ +package com.quickpick.ureca.user.controller; + +public class UserController { +} diff --git a/src/main/java/com/quickpick/ureca/user/domain/User.java b/src/main/java/com/quickpick/ureca/user/domain/User.java new file mode 100644 index 0000000..122ea72 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/user/domain/User.java @@ -0,0 +1,50 @@ +package com.quickpick.ureca.user.domain; + +import com.quickpick.ureca.reserve.domain.Reserve; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Table(name = "user") +@Entity +@Getter +@NoArgsConstructor +public class User { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "user_id") + private Long userId; + + @Column(nullable = false) + private String id; + + @Column(nullable = false) + private String password; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private String age; + + @Column(nullable = false) + private String gender; + + @CreatedDate + @Column(updatable = false) + private LocalDateTime created_at; + + @LastModifiedDate + private LocalDateTime updated_at; + + @OneToMany + @JoinColumn(name = "reserve_id") + private List reserveList = new ArrayList<>(); +} diff --git a/src/main/java/com/quickpick/ureca/user/repository/UserRepository.java b/src/main/java/com/quickpick/ureca/user/repository/UserRepository.java new file mode 100644 index 0000000..50abb0e --- /dev/null +++ b/src/main/java/com/quickpick/ureca/user/repository/UserRepository.java @@ -0,0 +1,4 @@ +package com.quickpick.ureca.user.repository; + +public class UserRepository { +} diff --git a/src/main/java/com/quickpick/ureca/user/service/UserService.java b/src/main/java/com/quickpick/ureca/user/service/UserService.java new file mode 100644 index 0000000..972e2b1 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/user/service/UserService.java @@ -0,0 +1,4 @@ +package com.quickpick.ureca.user.service; + +public class UserService { +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index eabf1a0..d94ccef 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -7,12 +7,7 @@ spring.jpa.properties.hibernate.format_sql=true spring.datasource.url=jdbc:mysql://localhost:3306/testdb?characterEncoding=UTF-8&serverTimezone=Asia/Seoul spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver -commit.hash=local -api.server.url=http://localhost:8080 - -spring.datasource.username=test -spring.datasource.password=testPW +# spring data source spring.jpa.hibernate.ddl-auto=create - - - +spring.datasource.username=root +spring.datasource.password=root \ No newline at end of file From e2deddab3e3a57c2f165483d73cb7e25d21020d0 Mon Sep 17 00:00:00 2001 From: etoile0626 Date: Wed, 30 Apr 2025 22:21:20 +0900 Subject: [PATCH 18/43] =?UTF-8?q?user,=20reserve=20=EA=B0=9D=EC=B2=B4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20(=EC=97=B0=EA=B4=80=20=EA=B4=80=EA=B3=84?= =?UTF-8?q?=20=EB=AF=B8=EC=99=84=EC=84=B1)=20(#1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../quickpick/ureca/reserve/domain/Reserve.java | 4 ++-- .../com/quickpick/ureca/user/domain/User.java | 15 ++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java b/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java index b8356e9..390e341 100644 --- a/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java +++ b/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java @@ -8,7 +8,7 @@ import java.time.LocalDateTime; -@Table(name = "user") +@Table @Entity @Getter @NoArgsConstructor @@ -22,7 +22,7 @@ public class Reserve { @Column(name = "user_id", nullable = false) private String userId; - @Column(nullable = false) + @Column(name = "status", nullable = false) private String status; @CreatedDate diff --git a/src/main/java/com/quickpick/ureca/user/domain/User.java b/src/main/java/com/quickpick/ureca/user/domain/User.java index 122ea72..619a9c4 100644 --- a/src/main/java/com/quickpick/ureca/user/domain/User.java +++ b/src/main/java/com/quickpick/ureca/user/domain/User.java @@ -11,7 +11,7 @@ import java.util.ArrayList; import java.util.List; -@Table(name = "user") +@Table @Entity @Getter @NoArgsConstructor @@ -22,19 +22,19 @@ public class User { @Column(name = "user_id") private Long userId; - @Column(nullable = false) + @Column(name = "id", nullable = false) private String id; - @Column(nullable = false) + @Column(name = "password", nullable = false) private String password; - @Column(nullable = false) + @Column(name = "name", nullable = false) private String name; - @Column(nullable = false) + @Column(name = "age", nullable = false) private String age; - @Column(nullable = false) + @Column(name = "gender", nullable = false) private String gender; @CreatedDate @@ -43,8 +43,9 @@ public class User { @LastModifiedDate private LocalDateTime updated_at; - +/* @OneToMany @JoinColumn(name = "reserve_id") private List reserveList = new ArrayList<>(); + */ } From 6f6741788eb9c7fde1f27601b236af495dc6e479 Mon Sep 17 00:00:00 2001 From: etoile0626 Date: Wed, 30 Apr 2025 22:41:56 +0900 Subject: [PATCH 19/43] =?UTF-8?q?user,=20reserve=20=EA=B0=9D=EC=B2=B4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20(=EC=97=B0=EA=B4=80=20=EA=B4=80=EA=B3=84?= =?UTF-8?q?=20=EB=8B=A8=EB=B0=A9=ED=96=A5)=20(#1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/quickpick/ureca/UrecaApplication.java | 1 - .../quickpick/ureca/reserve/domain/Reserve.java | 8 +++++--- .../com/quickpick/ureca/user/domain/User.java | 16 ++++++---------- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/quickpick/ureca/UrecaApplication.java b/src/main/java/com/quickpick/ureca/UrecaApplication.java index c68d0ed..5911fa6 100644 --- a/src/main/java/com/quickpick/ureca/UrecaApplication.java +++ b/src/main/java/com/quickpick/ureca/UrecaApplication.java @@ -2,7 +2,6 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.PropertySource; @SpringBootApplication public class UrecaApplication { diff --git a/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java b/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java index 390e341..778c5a9 100644 --- a/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java +++ b/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java @@ -1,5 +1,6 @@ package com.quickpick.ureca.reserve.domain; +import com.quickpick.ureca.user.domain.User; import jakarta.persistence.*; import lombok.Getter; import lombok.NoArgsConstructor; @@ -19,10 +20,11 @@ public class Reserve { @Column(name = "reserve_id") private Long reserveId; - @Column(name = "user_id", nullable = false) - private String userId; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", nullable = false) + private User user; - @Column(name = "status", nullable = false) + @Column(nullable = false) private String status; @CreatedDate diff --git a/src/main/java/com/quickpick/ureca/user/domain/User.java b/src/main/java/com/quickpick/ureca/user/domain/User.java index 619a9c4..bb04fd7 100644 --- a/src/main/java/com/quickpick/ureca/user/domain/User.java +++ b/src/main/java/com/quickpick/ureca/user/domain/User.java @@ -22,19 +22,19 @@ public class User { @Column(name = "user_id") private Long userId; - @Column(name = "id", nullable = false) + @Column(nullable = false) private String id; - @Column(name = "password", nullable = false) + @Column(nullable = false) private String password; - @Column(name = "name", nullable = false) + @Column(nullable = false) private String name; - @Column(name = "age", nullable = false) + @Column(nullable = false) private String age; - @Column(name = "gender", nullable = false) + @Column(nullable = false) private String gender; @CreatedDate @@ -43,9 +43,5 @@ public class User { @LastModifiedDate private LocalDateTime updated_at; -/* - @OneToMany - @JoinColumn(name = "reserve_id") - private List reserveList = new ArrayList<>(); - */ + } From 506174613efea1bc6757bcd2ecf1d797dedbbc79 Mon Sep 17 00:00:00 2001 From: etoile0626 Date: Wed, 30 Apr 2025 23:00:53 +0900 Subject: [PATCH 20/43] Ignore application.properties (#1) --- src/main/resources/application.properties | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 src/main/resources/application.properties diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties deleted file mode 100644 index d94ccef..0000000 --- a/src/main/resources/application.properties +++ /dev/null @@ -1,13 +0,0 @@ -spring.application.name=ureca - -# spring jpa -spring.jpa.database=mysql -spring.jpa.show-sql=true -spring.jpa.properties.hibernate.format_sql=true -spring.datasource.url=jdbc:mysql://localhost:3306/testdb?characterEncoding=UTF-8&serverTimezone=Asia/Seoul -spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver - -# spring data source -spring.jpa.hibernate.ddl-auto=create -spring.datasource.username=root -spring.datasource.password=root \ No newline at end of file From 5d00b4cf8a28edcbad10e0dbef96e48b96857ea5 Mon Sep 17 00:00:00 2001 From: etoile0626 Date: Wed, 30 Apr 2025 23:06:15 +0900 Subject: [PATCH 21/43] test (#1) --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 4284c4a..39fb52a 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,4 @@ out/ ### VS Code ### .vscode/ -**/src/main/resources/application_local.properties \ No newline at end of file +/src/main/resources/application.properties \ No newline at end of file From 45d84c9892ef2004bc2baa633cd8d4aeab36f08a Mon Sep 17 00:00:00 2001 From: Suhun0331 Date: Wed, 30 Apr 2025 17:25:17 +0900 Subject: [PATCH 22/43] Refactor : change CI range, delete DB id, pw (#1) --- .github/workflows/CI.yml | 6 +++--- src/main/resources/application.properties | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 src/main/resources/application.properties diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 10540c5..4331c41 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -2,9 +2,9 @@ name: CI FOR MVP on: push: - branches-ignore: - - main - - develop +# branches-ignore: +# - main +# - develop jobs: CI: diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..eabf1a0 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,18 @@ +spring.application.name=ureca + +# spring jpa +spring.jpa.database=mysql +spring.jpa.show-sql=true +spring.jpa.properties.hibernate.format_sql=true +spring.datasource.url=jdbc:mysql://localhost:3306/testdb?characterEncoding=UTF-8&serverTimezone=Asia/Seoul +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver + +commit.hash=local +api.server.url=http://localhost:8080 + +spring.datasource.username=test +spring.datasource.password=testPW +spring.jpa.hibernate.ddl-auto=create + + + From a9edf2fdf5496cad78f72b491a74309fc06fc0fe Mon Sep 17 00:00:00 2001 From: etoile0626 Date: Wed, 30 Apr 2025 23:10:12 +0900 Subject: [PATCH 23/43] =?UTF-8?q?user,=20reserve=20=EA=B0=9D=EC=B2=B4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20(=EC=97=B0=EA=B4=80=20=EA=B4=80=EA=B3=84?= =?UTF-8?q?=20=EB=8B=A8=EB=B0=A9=ED=96=A5)=20(#1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.properties | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index eabf1a0..d94ccef 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -7,12 +7,7 @@ spring.jpa.properties.hibernate.format_sql=true spring.datasource.url=jdbc:mysql://localhost:3306/testdb?characterEncoding=UTF-8&serverTimezone=Asia/Seoul spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver -commit.hash=local -api.server.url=http://localhost:8080 - -spring.datasource.username=test -spring.datasource.password=testPW +# spring data source spring.jpa.hibernate.ddl-auto=create - - - +spring.datasource.username=root +spring.datasource.password=root \ No newline at end of file From fa6b1f886c6637b7f93c5e9fca6e6d1ba4a21d1a Mon Sep 17 00:00:00 2001 From: ghdtmdalsda Date: Thu, 1 May 2025 01:30:22 +0900 Subject: [PATCH 24/43] =?UTF-8?q?feat:=20Ticket=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EC=B6=94=EA=B0=80=20(#1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../quickpick/ureca/ticket/domain/Ticket.java | 46 +++++++++++++++++++ .../ticket/repository/TicketRepository.java | 7 +++ .../com/quickpick/ureca/user/domain/User.java | 9 ++++ 3 files changed, 62 insertions(+) create mode 100644 src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java create mode 100644 src/main/java/com/quickpick/ureca/ticket/repository/TicketRepository.java diff --git a/src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java b/src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java new file mode 100644 index 0000000..afa416c --- /dev/null +++ b/src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java @@ -0,0 +1,46 @@ +package com.quickpick.ureca.ticket.domain; + +import com.quickpick.ureca.user.domain.User; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Entity +@Table(name = "ticket") +@Getter +@NoArgsConstructor +public class Ticket { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "ticket_id") + private Long ticketId; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private int quantity; + + @Column(nullable = false) + private LocalDateTime startDate; + + @Column(nullable = false) + private LocalDateTime reserveDate; + + @CreatedDate + @Column(updatable = false) + private LocalDateTime createdAt; + + @LastModifiedDate + private LocalDateTime updatedAt; + + @ManyToMany(mappedBy = "tickets") + private List users = new ArrayList<>(); +} diff --git a/src/main/java/com/quickpick/ureca/ticket/repository/TicketRepository.java b/src/main/java/com/quickpick/ureca/ticket/repository/TicketRepository.java new file mode 100644 index 0000000..34b9f66 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/ticket/repository/TicketRepository.java @@ -0,0 +1,7 @@ +package com.quickpick.ureca.ticket.repository; + +import com.quickpick.ureca.ticket.domain.Ticket; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface TicketRepository extends JpaRepository { +} diff --git a/src/main/java/com/quickpick/ureca/user/domain/User.java b/src/main/java/com/quickpick/ureca/user/domain/User.java index bb04fd7..8716084 100644 --- a/src/main/java/com/quickpick/ureca/user/domain/User.java +++ b/src/main/java/com/quickpick/ureca/user/domain/User.java @@ -1,6 +1,7 @@ package com.quickpick.ureca.user.domain; import com.quickpick.ureca.reserve.domain.Reserve; +import com.quickpick.ureca.ticket.domain.Ticket; import jakarta.persistence.*; import lombok.Getter; import lombok.NoArgsConstructor; @@ -44,4 +45,12 @@ public class User { @LastModifiedDate private LocalDateTime updated_at; + @ManyToMany + @JoinTable( + name = "user_ticket", + joinColumns = @JoinColumn(name = "user_id"), + inverseJoinColumns = @JoinColumn(name = "ticket_id") + ) + private List tickets = new ArrayList<>(); + } From b3020b688408958078c4931207cff1b00970c86d Mon Sep 17 00:00:00 2001 From: ghdtmdalsda Date: Thu, 1 May 2025 09:43:20 +0900 Subject: [PATCH 25/43] =?UTF-8?q?feat:=20User=EC=99=80=20Ticket=20?= =?UTF-8?q?=EC=82=AC=EC=9D=B4=EC=9D=98=20=EB=8B=A4=EB=8C=80=EB=8B=A4=20?= =?UTF-8?q?=EB=A7=A4=ED=95=91=20UserTicket=20=EB=8F=84=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=EC=9C=BC=EB=A1=9C=20=EB=B6=84=EB=A6=AC=20?= =?UTF-8?q?(#1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../quickpick/ureca/ticket/domain/Ticket.java | 5 ++-- .../com/quickpick/ureca/user/domain/User.java | 10 ++----- .../ureca/userticket/domain/UserTicket.java | 28 +++++++++++++++++++ 3 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/quickpick/ureca/userticket/domain/UserTicket.java diff --git a/src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java b/src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java index afa416c..0fd9d77 100644 --- a/src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java +++ b/src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java @@ -1,6 +1,7 @@ package com.quickpick.ureca.ticket.domain; import com.quickpick.ureca.user.domain.User; +import com.quickpick.ureca.userticket.domain.UserTicket; import jakarta.persistence.*; import lombok.Getter; import lombok.NoArgsConstructor; @@ -41,6 +42,6 @@ public class Ticket { @LastModifiedDate private LocalDateTime updatedAt; - @ManyToMany(mappedBy = "tickets") - private List users = new ArrayList<>(); + @OneToMany(mappedBy = "ticket", cascade = CascadeType.ALL, orphanRemoval = true) + private List userTickets = new ArrayList<>(); } diff --git a/src/main/java/com/quickpick/ureca/user/domain/User.java b/src/main/java/com/quickpick/ureca/user/domain/User.java index 8716084..2792033 100644 --- a/src/main/java/com/quickpick/ureca/user/domain/User.java +++ b/src/main/java/com/quickpick/ureca/user/domain/User.java @@ -2,6 +2,7 @@ import com.quickpick.ureca.reserve.domain.Reserve; import com.quickpick.ureca.ticket.domain.Ticket; +import com.quickpick.ureca.userticket.domain.UserTicket; import jakarta.persistence.*; import lombok.Getter; import lombok.NoArgsConstructor; @@ -45,12 +46,7 @@ public class User { @LastModifiedDate private LocalDateTime updated_at; - @ManyToMany - @JoinTable( - name = "user_ticket", - joinColumns = @JoinColumn(name = "user_id"), - inverseJoinColumns = @JoinColumn(name = "ticket_id") - ) - private List tickets = new ArrayList<>(); + @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) + private List userTickets = new ArrayList<>(); } diff --git a/src/main/java/com/quickpick/ureca/userticket/domain/UserTicket.java b/src/main/java/com/quickpick/ureca/userticket/domain/UserTicket.java new file mode 100644 index 0000000..8825698 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/userticket/domain/UserTicket.java @@ -0,0 +1,28 @@ +package com.quickpick.ureca.userticket.domain; + +import com.quickpick.ureca.ticket.domain.Ticket; +import com.quickpick.ureca.user.domain.User; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Table +@Getter +@NoArgsConstructor +public class UserTicket { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "user_ticket_id") + private Long userTicketId; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id") + private User user; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "ticket_id") + private Ticket ticket; + +} \ No newline at end of file From d57424c3b66598d8b40acf9464b4de99ebebe77d Mon Sep 17 00:00:00 2001 From: Suhun0331 Date: Thu, 1 May 2025 10:15:24 +0900 Subject: [PATCH 26/43] Feat : CI test --- .github/workflows/CI.yml | 21 +++++++++++++++++++++ .gitignore | 2 ++ 2 files changed, 23 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 4331c41..1f0c956 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -37,6 +37,27 @@ jobs: id: slug run: echo "sha7=$(echo ${GITHUB_SHA} | cut -c1-7)" >> $GITHUB_OUTPUT + - name: Create application.properties + run: | + cat < ./src/test/resources/application.properties + spring.application.name=ureca + + spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver + spring.datasource.url=jdbc:mysql://localhost:3306/testDB?characterEncoding=UTF-8&serverTimezone=Asia/Seoul + spring.datasource.username=test + spring.datasource.password=testPW + + # spring jpa + spring.jpa.database=mysql + spring.jpa.properties.hibernate.show_sql=true + spring.jpa.hibernate.ddl-auto=create-drop + spring.jpa.properties.hibernate.format_sql=true + EOT + shell: bash + + + + - name: Grant execute permission for gradlew run: chmod +x ./gradlew diff --git a/.gitignore b/.gitignore index c2065bc..c489d28 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,5 @@ out/ ### VS Code ### .vscode/ + + From daf4c662bea60d027c502ddc4089b7a132c535b7 Mon Sep 17 00:00:00 2001 From: Suhun0331 Date: Thu, 1 May 2025 10:16:35 +0900 Subject: [PATCH 27/43] Add text --- src/main/resources/text | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/main/resources/text diff --git a/src/main/resources/text b/src/main/resources/text new file mode 100644 index 0000000..945c9b4 --- /dev/null +++ b/src/main/resources/text @@ -0,0 +1 @@ +. \ No newline at end of file From 4f36511273222cf6fea85d2c85e8579fde3fce0e Mon Sep 17 00:00:00 2001 From: Suhun0331 Date: Thu, 1 May 2025 10:17:19 +0900 Subject: [PATCH 28/43] Fix path --- .github/workflows/CI.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 1f0c956..5e4e8f3 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -39,7 +39,7 @@ jobs: - name: Create application.properties run: | - cat < ./src/test/resources/application.properties + cat < ./src/main/resources/application.properties spring.application.name=ureca spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver @@ -55,9 +55,6 @@ jobs: EOT shell: bash - - - - name: Grant execute permission for gradlew run: chmod +x ./gradlew From 53d6da2fef9fe9881ff6df8ec9df968bc5425420 Mon Sep 17 00:00:00 2001 From: SuHun <104614675+Suhun0331@users.noreply.github.com> Date: Thu, 1 May 2025 10:19:51 +0900 Subject: [PATCH 29/43] Delete src/main/resources/application.properties --- src/main/resources/application.properties | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 src/main/resources/application.properties diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties deleted file mode 100644 index dc0c1db..0000000 --- a/src/main/resources/application.properties +++ /dev/null @@ -1,11 +0,0 @@ -spring.application.name=ureca - -# spring jpa -spring.jpa.database=mysql -spring.jpa.show-sql=true -spring.jpa.properties.hibernate.format_sql=true -spring.datasource.url=jdbc:mysql://localhost:3306/testdb?characterEncoding=UTF-8&serverTimezone=Asia/Seoul -spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver - -# spring data source -spring.jpa.hibernate.ddl-auto=create \ No newline at end of file From ab4ef538491732ef315121aad9909bd6d08bd740 Mon Sep 17 00:00:00 2001 From: etoile0626 Date: Thu, 1 May 2025 10:35:15 +0900 Subject: [PATCH 30/43] feat: test (#1) --- .github/workflows/CI.yml | 18 ++++++++++++++++++ src/main/resources/application.properties | 4 ++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 4331c41..5e4e8f3 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -37,6 +37,24 @@ jobs: id: slug run: echo "sha7=$(echo ${GITHUB_SHA} | cut -c1-7)" >> $GITHUB_OUTPUT + - name: Create application.properties + run: | + cat < ./src/main/resources/application.properties + spring.application.name=ureca + + spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver + spring.datasource.url=jdbc:mysql://localhost:3306/testDB?characterEncoding=UTF-8&serverTimezone=Asia/Seoul + spring.datasource.username=test + spring.datasource.password=testPW + + # spring jpa + spring.jpa.database=mysql + spring.jpa.properties.hibernate.show_sql=true + spring.jpa.hibernate.ddl-auto=create-drop + spring.jpa.properties.hibernate.format_sql=true + EOT + shell: bash + - name: Grant execute permission for gradlew run: chmod +x ./gradlew diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index eabf1a0..8e8a429 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -10,8 +10,8 @@ spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver commit.hash=local api.server.url=http://localhost:8080 -spring.datasource.username=test -spring.datasource.password=testPW +spring.datasource.username=root +spring.datasource.password=root spring.jpa.hibernate.ddl-auto=create From 26e87a6fdd66db433b29a8a91db7d8bfc19ebe98 Mon Sep 17 00:00:00 2001 From: etoile0626 Date: Thu, 1 May 2025 10:35:46 +0900 Subject: [PATCH 31/43] feat: test (#1) --- src/main/resources/application.properties | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8e8a429..7e11d76 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -7,9 +7,6 @@ spring.jpa.properties.hibernate.format_sql=true spring.datasource.url=jdbc:mysql://localhost:3306/testdb?characterEncoding=UTF-8&serverTimezone=Asia/Seoul spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver -commit.hash=local -api.server.url=http://localhost:8080 - spring.datasource.username=root spring.datasource.password=root spring.jpa.hibernate.ddl-auto=create From c58044d71c2d94e62a8584d60a03e7f0270591ef Mon Sep 17 00:00:00 2001 From: Suhun0331 Date: Thu, 1 May 2025 10:49:32 +0900 Subject: [PATCH 32/43] Feat : extend baseEntity --- .../com/quickpick/ureca/UrecaApplication.java | 4 +++ .../ureca/common/domain/BaseEntity.java | 26 +++++++++++++++++++ .../ureca/reserve/domain/Reserve.java | 11 ++------ .../quickpick/ureca/ticket/domain/Ticket.java | 9 +------ .../com/quickpick/ureca/user/domain/User.java | 9 +------ 5 files changed, 34 insertions(+), 25 deletions(-) create mode 100644 src/main/java/com/quickpick/ureca/common/domain/BaseEntity.java diff --git a/src/main/java/com/quickpick/ureca/UrecaApplication.java b/src/main/java/com/quickpick/ureca/UrecaApplication.java index 5911fa6..8be528e 100644 --- a/src/main/java/com/quickpick/ureca/UrecaApplication.java +++ b/src/main/java/com/quickpick/ureca/UrecaApplication.java @@ -2,8 +2,12 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication +@EnableJpaAuditing +@EnableScheduling public class UrecaApplication { public static void main(String[] args) { diff --git a/src/main/java/com/quickpick/ureca/common/domain/BaseEntity.java b/src/main/java/com/quickpick/ureca/common/domain/BaseEntity.java new file mode 100644 index 0000000..e4ac893 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/common/domain/BaseEntity.java @@ -0,0 +1,26 @@ +package com.quickpick.ureca.common.domain; + +import jakarta.persistence.Column; +import jakarta.persistence.EntityListeners; +import jakarta.persistence.MappedSuperclass; +import lombok.Getter; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import java.time.LocalDateTime; + +@Getter +@MappedSuperclass +@EntityListeners(AuditingEntityListener.class) +public abstract class BaseEntity { + @CreatedDate + @Column(length = 6, name = "created_at", updatable = false) + private LocalDateTime createdAt; + + @LastModifiedDate + @Column(length = 6, name = "updated_at") + private LocalDateTime updatedAt; + +} + diff --git a/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java b/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java index 778c5a9..150de8c 100644 --- a/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java +++ b/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java @@ -1,5 +1,6 @@ package com.quickpick.ureca.reserve.domain; +import com.quickpick.ureca.common.domain.BaseEntity; import com.quickpick.ureca.user.domain.User; import jakarta.persistence.*; import lombok.Getter; @@ -13,7 +14,7 @@ @Entity @Getter @NoArgsConstructor -public class Reserve { +public class Reserve extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -26,12 +27,4 @@ public class Reserve { @Column(nullable = false) private String status; - - @CreatedDate - @Column(nullable = false) - private LocalDateTime created_at; - - @LastModifiedDate - @Column(nullable = false) - private LocalDateTime updated_at; } diff --git a/src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java b/src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java index 0fd9d77..10fd3c8 100644 --- a/src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java +++ b/src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java @@ -16,7 +16,7 @@ @Table(name = "ticket") @Getter @NoArgsConstructor -public class Ticket { +public class Ticket extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -35,13 +35,6 @@ public class Ticket { @Column(nullable = false) private LocalDateTime reserveDate; - @CreatedDate - @Column(updatable = false) - private LocalDateTime createdAt; - - @LastModifiedDate - private LocalDateTime updatedAt; - @OneToMany(mappedBy = "ticket", cascade = CascadeType.ALL, orphanRemoval = true) private List userTickets = new ArrayList<>(); } diff --git a/src/main/java/com/quickpick/ureca/user/domain/User.java b/src/main/java/com/quickpick/ureca/user/domain/User.java index 2792033..f5a2fdb 100644 --- a/src/main/java/com/quickpick/ureca/user/domain/User.java +++ b/src/main/java/com/quickpick/ureca/user/domain/User.java @@ -17,7 +17,7 @@ @Entity @Getter @NoArgsConstructor -public class User { +public class User extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -39,13 +39,6 @@ public class User { @Column(nullable = false) private String gender; - @CreatedDate - @Column(updatable = false) - private LocalDateTime created_at; - - @LastModifiedDate - private LocalDateTime updated_at; - @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) private List userTickets = new ArrayList<>(); From 3f0a62f3608e4d7387e4742d808278b03d19db87 Mon Sep 17 00:00:00 2001 From: Suhun0331 Date: Thu, 1 May 2025 10:50:44 +0900 Subject: [PATCH 33/43] Refactor : clear unused import --- .../java/com/quickpick/ureca/reserve/domain/Reserve.java | 4 ---- src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java | 4 +--- src/main/java/com/quickpick/ureca/user/domain/User.java | 6 +----- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java b/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java index 150de8c..b4ebcda 100644 --- a/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java +++ b/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java @@ -5,10 +5,6 @@ import jakarta.persistence.*; import lombok.Getter; import lombok.NoArgsConstructor; -import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.annotation.LastModifiedDate; - -import java.time.LocalDateTime; @Table @Entity diff --git a/src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java b/src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java index 10fd3c8..2a0e3e9 100644 --- a/src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java +++ b/src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java @@ -1,12 +1,10 @@ package com.quickpick.ureca.ticket.domain; -import com.quickpick.ureca.user.domain.User; +import com.quickpick.ureca.common.domain.BaseEntity; import com.quickpick.ureca.userticket.domain.UserTicket; import jakarta.persistence.*; import lombok.Getter; import lombok.NoArgsConstructor; -import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.annotation.LastModifiedDate; import java.time.LocalDateTime; import java.util.ArrayList; diff --git a/src/main/java/com/quickpick/ureca/user/domain/User.java b/src/main/java/com/quickpick/ureca/user/domain/User.java index f5a2fdb..86eaaca 100644 --- a/src/main/java/com/quickpick/ureca/user/domain/User.java +++ b/src/main/java/com/quickpick/ureca/user/domain/User.java @@ -1,15 +1,11 @@ package com.quickpick.ureca.user.domain; -import com.quickpick.ureca.reserve.domain.Reserve; -import com.quickpick.ureca.ticket.domain.Ticket; +import com.quickpick.ureca.common.domain.BaseEntity; import com.quickpick.ureca.userticket.domain.UserTicket; import jakarta.persistence.*; import lombok.Getter; import lombok.NoArgsConstructor; -import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.annotation.LastModifiedDate; -import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; From 62548b1b09694998f7b4a31dddcd710649414efd Mon Sep 17 00:00:00 2001 From: Suhun0331 Date: Thu, 1 May 2025 10:58:47 +0900 Subject: [PATCH 34/43] =?UTF-8?q?Feat=20:=20=EC=9D=B4=EA=B1=B0=EB=B6=80?= =?UTF-8?q?=ED=84=B0=20=EB=8B=A4=EC=8B=9C=20=EC=8B=9C=EC=9E=91=20~?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.properties | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 src/main/resources/application.properties diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties deleted file mode 100644 index 7e11d76..0000000 --- a/src/main/resources/application.properties +++ /dev/null @@ -1,15 +0,0 @@ -spring.application.name=ureca - -# spring jpa -spring.jpa.database=mysql -spring.jpa.show-sql=true -spring.jpa.properties.hibernate.format_sql=true -spring.datasource.url=jdbc:mysql://localhost:3306/testdb?characterEncoding=UTF-8&serverTimezone=Asia/Seoul -spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver - -spring.datasource.username=root -spring.datasource.password=root -spring.jpa.hibernate.ddl-auto=create - - - From f66c9f36067023234a8aed95ad669c59208b6153 Mon Sep 17 00:00:00 2001 From: Suhun0331 Date: Thu, 1 May 2025 11:00:50 +0900 Subject: [PATCH 35/43] =?UTF-8?q?Feat=20:=20=EC=9D=B4=EA=B1=B0=EB=B6=80?= =?UTF-8?q?=ED=84=B0=20=EB=8B=A4=EC=8B=9C=20=EC=8B=9C=EC=9E=91=20~=20ver?= =?UTF-8?q?=5F2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/text | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/main/resources/text diff --git a/src/main/resources/text b/src/main/resources/text new file mode 100644 index 0000000..945c9b4 --- /dev/null +++ b/src/main/resources/text @@ -0,0 +1 @@ +. \ No newline at end of file From a73d1313a8ac49a0239f324a359b3ed709cba78a Mon Sep 17 00:00:00 2001 From: sangyunpark99 Date: Fri, 2 May 2025 11:05:33 +0900 Subject: [PATCH 36/43] =?UTF-8?q?setting:=20feat/v3=20=EB=B8=8C=EB=9E=9C?= =?UTF-8?q?=EC=B9=98=20=EB=93=B1=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../reserve/controller/ReserveController.java | 4 -- .../ureca/reserve/domain/Reserve.java | 26 ------------- .../reserve/repository/ReserveRepository.java | 4 -- .../ureca/reserve/service/ReserveService.java | 4 -- .../quickpick/ureca/ticket/domain/Ticket.java | 38 ------------------- .../ticket/repository/TicketRepository.java | 7 ---- .../ureca/userticket/domain/UserTicket.java | 28 -------------- 7 files changed, 111 deletions(-) delete mode 100644 src/main/java/com/quickpick/ureca/reserve/controller/ReserveController.java delete mode 100644 src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java delete mode 100644 src/main/java/com/quickpick/ureca/reserve/repository/ReserveRepository.java delete mode 100644 src/main/java/com/quickpick/ureca/reserve/service/ReserveService.java delete mode 100644 src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java delete mode 100644 src/main/java/com/quickpick/ureca/ticket/repository/TicketRepository.java delete mode 100644 src/main/java/com/quickpick/ureca/userticket/domain/UserTicket.java diff --git a/src/main/java/com/quickpick/ureca/reserve/controller/ReserveController.java b/src/main/java/com/quickpick/ureca/reserve/controller/ReserveController.java deleted file mode 100644 index 7b3818a..0000000 --- a/src/main/java/com/quickpick/ureca/reserve/controller/ReserveController.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.quickpick.ureca.reserve.controller; - -public class ReserveController { -} diff --git a/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java b/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java deleted file mode 100644 index b4ebcda..0000000 --- a/src/main/java/com/quickpick/ureca/reserve/domain/Reserve.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.quickpick.ureca.reserve.domain; - -import com.quickpick.ureca.common.domain.BaseEntity; -import com.quickpick.ureca.user.domain.User; -import jakarta.persistence.*; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Table -@Entity -@Getter -@NoArgsConstructor -public class Reserve extends BaseEntity { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "reserve_id") - private Long reserveId; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "user_id", nullable = false) - private User user; - - @Column(nullable = false) - private String status; -} diff --git a/src/main/java/com/quickpick/ureca/reserve/repository/ReserveRepository.java b/src/main/java/com/quickpick/ureca/reserve/repository/ReserveRepository.java deleted file mode 100644 index d9dfba9..0000000 --- a/src/main/java/com/quickpick/ureca/reserve/repository/ReserveRepository.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.quickpick.ureca.reserve.repository; - -public class ReserveRepository { -} diff --git a/src/main/java/com/quickpick/ureca/reserve/service/ReserveService.java b/src/main/java/com/quickpick/ureca/reserve/service/ReserveService.java deleted file mode 100644 index 28c25c2..0000000 --- a/src/main/java/com/quickpick/ureca/reserve/service/ReserveService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.quickpick.ureca.reserve.service; - -public class ReserveService { -} diff --git a/src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java b/src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java deleted file mode 100644 index 2a0e3e9..0000000 --- a/src/main/java/com/quickpick/ureca/ticket/domain/Ticket.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.quickpick.ureca.ticket.domain; - -import com.quickpick.ureca.common.domain.BaseEntity; -import com.quickpick.ureca.userticket.domain.UserTicket; -import jakarta.persistence.*; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; - -@Entity -@Table(name = "ticket") -@Getter -@NoArgsConstructor -public class Ticket extends BaseEntity { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "ticket_id") - private Long ticketId; - - @Column(nullable = false) - private String name; - - @Column(nullable = false) - private int quantity; - - @Column(nullable = false) - private LocalDateTime startDate; - - @Column(nullable = false) - private LocalDateTime reserveDate; - - @OneToMany(mappedBy = "ticket", cascade = CascadeType.ALL, orphanRemoval = true) - private List userTickets = new ArrayList<>(); -} diff --git a/src/main/java/com/quickpick/ureca/ticket/repository/TicketRepository.java b/src/main/java/com/quickpick/ureca/ticket/repository/TicketRepository.java deleted file mode 100644 index 34b9f66..0000000 --- a/src/main/java/com/quickpick/ureca/ticket/repository/TicketRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.quickpick.ureca.ticket.repository; - -import com.quickpick.ureca.ticket.domain.Ticket; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface TicketRepository extends JpaRepository { -} diff --git a/src/main/java/com/quickpick/ureca/userticket/domain/UserTicket.java b/src/main/java/com/quickpick/ureca/userticket/domain/UserTicket.java deleted file mode 100644 index 8825698..0000000 --- a/src/main/java/com/quickpick/ureca/userticket/domain/UserTicket.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.quickpick.ureca.userticket.domain; - -import com.quickpick.ureca.ticket.domain.Ticket; -import com.quickpick.ureca.user.domain.User; -import jakarta.persistence.*; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Entity -@Table -@Getter -@NoArgsConstructor -public class UserTicket { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "user_ticket_id") - private Long userTicketId; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "user_id") - private User user; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "ticket_id") - private Ticket ticket; - -} \ No newline at end of file From 08aa69ff89bd26b917a6a14e0bf2d9dfb933297a Mon Sep 17 00:00:00 2001 From: sangyunpark99 Date: Sat, 3 May 2025 09:27:45 +0900 Subject: [PATCH 37/43] =?UTF-8?q?feat:=20V3=20Kafka=20=EB=B2=84=EC=A0=84?= =?UTF-8?q?=201=EB=B2=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 5 ++ gradlew | 0 .../quickpick/ureca/init/InitDataLoader.java | 54 +++++++++++++++++++ .../ureca/reserve/v3/domain/Reserve.java | 27 ++++++++++ .../reserve/v3/domain/ReserveStatus.java | 5 ++ .../ureca/ticket/v3/ExceptionHandlers.java | 15 ++++++ .../v3/controller/TicketControllerV3.java | 20 +++++++ .../ureca/ticket/v3/domain/Ticket.java | 34 ++++++++++++ .../ticket/v3/event/TicketPurchaseEvent.java | 18 +++++++ .../ticket/v3/kafka/TicketEventConsumer.java | 47 ++++++++++++++++ .../ticket/v3/kafka/TicketEventProducer.java | 18 +++++++ .../v3/repository/RedisStockRepository.java | 52 ++++++++++++++++++ .../v3/repository/ReserveRepository.java | 7 +++ .../v3/repository/TicketRepository.java | 14 +++++ .../ticket/v3/service/TicketServiceV3.java | 40 ++++++++++++++ .../ureca/user/controller/UserController.java | 4 -- .../ureca/user/repository/UserRepository.java | 4 -- .../ureca/user/service/UserService.java | 4 -- .../ureca/user/v3/constants/Gender.java | 5 ++ .../user/v3/controller/UserController.java | 22 ++++++++ .../ureca/user/{ => v3}/domain/User.java | 20 ++++--- .../ureca/user/v3/dto/UserCreateRequest.java | 10 ++++ .../user/v3/repository/UserRepository.java | 7 +++ .../ureca/user/v3/service/UserService.java | 30 +++++++++++ .../userticket/v3/domain/UserTicket.java | 25 +++++++++ .../v3/repository/UserTicketRepository.java | 8 +++ .../ureca/UrecaApplicationTests.java | 26 ++++----- 27 files changed, 485 insertions(+), 36 deletions(-) mode change 100644 => 100755 gradlew create mode 100644 src/main/java/com/quickpick/ureca/init/InitDataLoader.java create mode 100644 src/main/java/com/quickpick/ureca/reserve/v3/domain/Reserve.java create mode 100644 src/main/java/com/quickpick/ureca/reserve/v3/domain/ReserveStatus.java create mode 100644 src/main/java/com/quickpick/ureca/ticket/v3/ExceptionHandlers.java create mode 100644 src/main/java/com/quickpick/ureca/ticket/v3/controller/TicketControllerV3.java create mode 100644 src/main/java/com/quickpick/ureca/ticket/v3/domain/Ticket.java create mode 100644 src/main/java/com/quickpick/ureca/ticket/v3/event/TicketPurchaseEvent.java create mode 100644 src/main/java/com/quickpick/ureca/ticket/v3/kafka/TicketEventConsumer.java create mode 100644 src/main/java/com/quickpick/ureca/ticket/v3/kafka/TicketEventProducer.java create mode 100644 src/main/java/com/quickpick/ureca/ticket/v3/repository/RedisStockRepository.java create mode 100644 src/main/java/com/quickpick/ureca/ticket/v3/repository/ReserveRepository.java create mode 100644 src/main/java/com/quickpick/ureca/ticket/v3/repository/TicketRepository.java create mode 100644 src/main/java/com/quickpick/ureca/ticket/v3/service/TicketServiceV3.java delete mode 100644 src/main/java/com/quickpick/ureca/user/controller/UserController.java delete mode 100644 src/main/java/com/quickpick/ureca/user/repository/UserRepository.java delete mode 100644 src/main/java/com/quickpick/ureca/user/service/UserService.java create mode 100644 src/main/java/com/quickpick/ureca/user/v3/constants/Gender.java create mode 100644 src/main/java/com/quickpick/ureca/user/v3/controller/UserController.java rename src/main/java/com/quickpick/ureca/user/{ => v3}/domain/User.java (62%) create mode 100644 src/main/java/com/quickpick/ureca/user/v3/dto/UserCreateRequest.java create mode 100644 src/main/java/com/quickpick/ureca/user/v3/repository/UserRepository.java create mode 100644 src/main/java/com/quickpick/ureca/user/v3/service/UserService.java create mode 100644 src/main/java/com/quickpick/ureca/userticket/v3/domain/UserTicket.java create mode 100644 src/main/java/com/quickpick/ureca/userticket/v3/repository/UserTicketRepository.java diff --git a/build.gradle b/build.gradle index d903a73..00d8539 100644 --- a/build.gradle +++ b/build.gradle @@ -28,6 +28,11 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-data-redis' + implementation 'org.springframework.kafka:spring-kafka' + implementation 'com.fasterxml.jackson.core:jackson-databind' + + testImplementation 'org.springframework.kafka:spring-kafka-test' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.mysql:mysql-connector-j' annotationProcessor 'org.projectlombok:lombok' diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/src/main/java/com/quickpick/ureca/init/InitDataLoader.java b/src/main/java/com/quickpick/ureca/init/InitDataLoader.java new file mode 100644 index 0000000..303b173 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/init/InitDataLoader.java @@ -0,0 +1,54 @@ +package com.quickpick.ureca.init; + +import com.quickpick.ureca.ticket.v3.domain.Ticket; +import com.quickpick.ureca.ticket.v3.repository.RedisStockRepository; +import com.quickpick.ureca.ticket.v3.repository.TicketRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.boot.CommandLineRunner; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Component; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Component +@RequiredArgsConstructor +public class InitDataLoader implements CommandLineRunner { + + private final TicketRepository ticketRepository; + private final RedisStockRepository redisStockRepository; + private final JdbcTemplate jdbcTemplate; + + @Override + public void run(String... args) { + String sql = "INSERT INTO user (id, name, age, gender, password) VALUES (?, ?, ?, ?, ?)"; + + List batchArgs = new ArrayList<>(); + + for (long i = 1; i <= 100_000; i++) { + batchArgs.add(new Object[]{ + "abc" + i, + "user" + i, + (int) i, + "MALE", // enum은 문자열로 저장한다고 가정 + "password" + i + }); + } + + jdbcTemplate.batchUpdate(sql, batchArgs); + System.out.println("=== 10만명 유저 생성 완료 ==="); + + + Ticket ticket = Ticket.builder() + .name("ticket") + .quantity(1000L) + .reserveTime(LocalDateTime.now()) + .startDate(LocalDate.now()) + .build(); + + Ticket saveTicket = ticketRepository.save(ticket); + redisStockRepository.setTicket(saveTicket.getId(), 1000L); + } +} diff --git a/src/main/java/com/quickpick/ureca/reserve/v3/domain/Reserve.java b/src/main/java/com/quickpick/ureca/reserve/v3/domain/Reserve.java new file mode 100644 index 0000000..e0506fd --- /dev/null +++ b/src/main/java/com/quickpick/ureca/reserve/v3/domain/Reserve.java @@ -0,0 +1,27 @@ +package com.quickpick.ureca.reserve.v3.domain; + +import com.quickpick.ureca.common.domain.BaseEntity; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.NoArgsConstructor; + +@Entity +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Reserve extends BaseEntity { + + @Column(name = "reserve_id") + @Id @GeneratedValue + private Long id; + + @Column(name = "user_id") + private Long userId; + + @Column(nullable = false) + private ReserveStatus status; +} diff --git a/src/main/java/com/quickpick/ureca/reserve/v3/domain/ReserveStatus.java b/src/main/java/com/quickpick/ureca/reserve/v3/domain/ReserveStatus.java new file mode 100644 index 0000000..3aa91f4 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/reserve/v3/domain/ReserveStatus.java @@ -0,0 +1,5 @@ +package com.quickpick.ureca.reserve.v3.domain; + +public enum ReserveStatus { + SUCCESS, FAIL +} diff --git a/src/main/java/com/quickpick/ureca/ticket/v3/ExceptionHandlers.java b/src/main/java/com/quickpick/ureca/ticket/v3/ExceptionHandlers.java new file mode 100644 index 0000000..48d9fbf --- /dev/null +++ b/src/main/java/com/quickpick/ureca/ticket/v3/ExceptionHandlers.java @@ -0,0 +1,15 @@ +package com.quickpick.ureca.ticket.v3; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +@ControllerAdvice +public class ExceptionHandlers { + + @ExceptionHandler(RuntimeException.class) + public ResponseEntity handleFileException() { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("티켓팅 실패"); + } +} diff --git a/src/main/java/com/quickpick/ureca/ticket/v3/controller/TicketControllerV3.java b/src/main/java/com/quickpick/ureca/ticket/v3/controller/TicketControllerV3.java new file mode 100644 index 0000000..20aa353 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/ticket/v3/controller/TicketControllerV3.java @@ -0,0 +1,20 @@ +package com.quickpick.ureca.ticket.v3.controller; + +import com.quickpick.ureca.ticket.v3.service.TicketServiceV3; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +@RequestMapping("/v3/tickets") +@RequiredArgsConstructor +@RestController +public class TicketControllerV3 { + + private final TicketServiceV3 ticketServiceV3; + + @PostMapping("/{ticketId}/purchase") + public String purchaseTicket(@PathVariable Long ticketId, @RequestParam Long userId) { + ticketServiceV3.purchaseTicket(ticketId, userId, 1L); + return "success"; + } + +} diff --git a/src/main/java/com/quickpick/ureca/ticket/v3/domain/Ticket.java b/src/main/java/com/quickpick/ureca/ticket/v3/domain/Ticket.java new file mode 100644 index 0000000..54b04ae --- /dev/null +++ b/src/main/java/com/quickpick/ureca/ticket/v3/domain/Ticket.java @@ -0,0 +1,34 @@ +package com.quickpick.ureca.ticket.v3.domain; + +import com.quickpick.ureca.common.domain.BaseEntity; +import jakarta.persistence.*; +import lombok.*; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Entity +@Table(name = "tickets") +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Ticket extends BaseEntity { + + @Id + @Column(name = "ticket_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private Long quantity; + + @Column(nullable = false) + private LocalDate startDate; + + @Column(nullable = false) + private LocalDateTime reserveTime; +} diff --git a/src/main/java/com/quickpick/ureca/ticket/v3/event/TicketPurchaseEvent.java b/src/main/java/com/quickpick/ureca/ticket/v3/event/TicketPurchaseEvent.java new file mode 100644 index 0000000..9517800 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/ticket/v3/event/TicketPurchaseEvent.java @@ -0,0 +1,18 @@ +package com.quickpick.ureca.ticket.v3.event; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class TicketPurchaseEvent { + private String uuid; + private Long ticketId; + private Long userId; + private Long quantity; + private String time; +} \ No newline at end of file diff --git a/src/main/java/com/quickpick/ureca/ticket/v3/kafka/TicketEventConsumer.java b/src/main/java/com/quickpick/ureca/ticket/v3/kafka/TicketEventConsumer.java new file mode 100644 index 0000000..ac13142 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/ticket/v3/kafka/TicketEventConsumer.java @@ -0,0 +1,47 @@ +package com.quickpick.ureca.ticket.v3.kafka; + +import com.quickpick.ureca.reserve.v3.domain.Reserve; +import com.quickpick.ureca.reserve.v3.domain.ReserveStatus; +import com.quickpick.ureca.ticket.v3.event.TicketPurchaseEvent; +import com.quickpick.ureca.ticket.v3.repository.ReserveRepository; +import com.quickpick.ureca.ticket.v3.repository.TicketRepository; +import com.quickpick.ureca.userticket.v3.domain.UserTicket; +import com.quickpick.ureca.userticket.v3.repository.UserTicketRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@Component +@RequiredArgsConstructor +public class TicketEventConsumer { + + private final TicketRepository ticketRepository; + private final UserTicketRepository userTicketRepository; + private final ReserveRepository reserveRepository; + + @KafkaListener(topics = "ticket.purchase", groupId = "ticket-service") + @Transactional + public void consume(final TicketPurchaseEvent event) { + log.info("ticker.purchased 이벤트 수신, 수신한 아이디 : {}", event.getUserId()); + + int result = ticketRepository.decreaseStock(event.getTicketId(), 1); + if(result == 0) { + throw new RuntimeException("티켓 수량 부족 및 존재하지 않음"); + } + + UserTicket userTicket = UserTicket.builder() + .ticketId(event.getTicketId()) + .userId(event.getUserId()) + .build(); + userTicketRepository.save(userTicket); + + Reserve reserve = Reserve.builder() + .userId(event.getUserId()) + .status(ReserveStatus.SUCCESS) + .build(); + reserveRepository.save(reserve); + } +} diff --git a/src/main/java/com/quickpick/ureca/ticket/v3/kafka/TicketEventProducer.java b/src/main/java/com/quickpick/ureca/ticket/v3/kafka/TicketEventProducer.java new file mode 100644 index 0000000..45e11ec --- /dev/null +++ b/src/main/java/com/quickpick/ureca/ticket/v3/kafka/TicketEventProducer.java @@ -0,0 +1,18 @@ +package com.quickpick.ureca.ticket.v3.kafka; + +import com.quickpick.ureca.ticket.v3.event.TicketPurchaseEvent; +import lombok.RequiredArgsConstructor; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class TicketEventProducer { + + private final KafkaTemplate kafkaTemplate; + private final String TOPIC = "ticket.purchase"; + + public void send(final TicketPurchaseEvent ticketPurchaseEvent) { + kafkaTemplate.send(TOPIC, ticketPurchaseEvent); + } +} diff --git a/src/main/java/com/quickpick/ureca/ticket/v3/repository/RedisStockRepository.java b/src/main/java/com/quickpick/ureca/ticket/v3/repository/RedisStockRepository.java new file mode 100644 index 0000000..183f4e1 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/ticket/v3/repository/RedisStockRepository.java @@ -0,0 +1,52 @@ +package com.quickpick.ureca.ticket.v3.repository; + +import lombok.RequiredArgsConstructor; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.script.DefaultRedisScript; +import org.springframework.stereotype.Component; + +import java.util.List; + + +@Component +@RequiredArgsConstructor +public class RedisStockRepository { + + private final RedisTemplate redisTemplate; + private final String DECREASE_SCRIPT = """ + local key = KEYS[1] + local decrease = tonumber(ARGV[1]) + local current = tonumber(redis.call('get', key)) + if current and current >= decrease then + return redis.call('decrby', key, decrease) + else + return -1 + end + """; + + private final String KEY_PREFIX = "ticket:"; + + private String getKey(final Long ticketId) { + return KEY_PREFIX + ticketId; + } + + public Long decrease(final Long ticketId, final Long quantity) { + return redisTemplate.execute( + new DefaultRedisScript<>(DECREASE_SCRIPT, Long.class), + List.of(getKey(ticketId)), + String.valueOf(quantity) + ); + } + + public void setTicket(final Long ticketId, final Long quantity) { + redisTemplate.opsForValue().set(getKey(ticketId), String.valueOf(quantity)); + } + + public boolean isExisted(final Long ticketId) { + return Boolean.TRUE.equals(redisTemplate.hasKey(getKey(ticketId))); + } + + public void increase(final Long ticketId, final Long quantity) { + redisTemplate.opsForValue().increment(getKey(ticketId), quantity); + } +} diff --git a/src/main/java/com/quickpick/ureca/ticket/v3/repository/ReserveRepository.java b/src/main/java/com/quickpick/ureca/ticket/v3/repository/ReserveRepository.java new file mode 100644 index 0000000..f3a5444 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/ticket/v3/repository/ReserveRepository.java @@ -0,0 +1,7 @@ +package com.quickpick.ureca.ticket.v3.repository; + +import com.quickpick.ureca.reserve.v3.domain.Reserve; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ReserveRepository extends JpaRepository { +} diff --git a/src/main/java/com/quickpick/ureca/ticket/v3/repository/TicketRepository.java b/src/main/java/com/quickpick/ureca/ticket/v3/repository/TicketRepository.java new file mode 100644 index 0000000..ecfc2b7 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/ticket/v3/repository/TicketRepository.java @@ -0,0 +1,14 @@ +package com.quickpick.ureca.ticket.v3.repository; + +import com.quickpick.ureca.ticket.v3.domain.Ticket; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +public interface TicketRepository extends JpaRepository { + + @Modifying + @Query(value = "UPDATE tickets SET quantity = quantity - :amount WHERE ticket_id = :ticketId", nativeQuery = true) + int decreaseStock(@Param("ticketId") Long ticketId, @Param("amount") int amount); +} \ No newline at end of file diff --git a/src/main/java/com/quickpick/ureca/ticket/v3/service/TicketServiceV3.java b/src/main/java/com/quickpick/ureca/ticket/v3/service/TicketServiceV3.java new file mode 100644 index 0000000..dcde3d8 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/ticket/v3/service/TicketServiceV3.java @@ -0,0 +1,40 @@ +package com.quickpick.ureca.ticket.v3.service; + +import com.quickpick.ureca.ticket.v3.event.TicketPurchaseEvent; +import com.quickpick.ureca.ticket.v3.kafka.TicketEventProducer; +import com.quickpick.ureca.ticket.v3.repository.RedisStockRepository; +import com.quickpick.ureca.user.v3.repository.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.UUID; + +@Service +@RequiredArgsConstructor +public class TicketServiceV3 { + + private final UserRepository userRepository; + private final RedisStockRepository redisStockRepository; + private final TicketEventProducer ticketEventProducer; + + public void purchaseTicket(final Long ticketId, final Long userId, final Long quantity) { + + if(!userRepository.existsById(userId)) { + throw new RuntimeException("존재하지 않는 사용자입니다."); + } + + Long result = redisStockRepository.decrease(ticketId, quantity); + if (result == -1L) { + throw new RuntimeException("티켓이 전부 소진되었습니다."); + } + + // 티켓 전부 소진시 메시지 발행 + TicketPurchaseEvent ticketPurchaseEvent = TicketPurchaseEvent.builder() + .uuid(UUID.randomUUID().toString()) + .ticketId(ticketId) + .userId(userId) + .quantity(quantity).build(); + + ticketEventProducer.send(ticketPurchaseEvent); + } +} diff --git a/src/main/java/com/quickpick/ureca/user/controller/UserController.java b/src/main/java/com/quickpick/ureca/user/controller/UserController.java deleted file mode 100644 index 5ea1b6a..0000000 --- a/src/main/java/com/quickpick/ureca/user/controller/UserController.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.quickpick.ureca.user.controller; - -public class UserController { -} diff --git a/src/main/java/com/quickpick/ureca/user/repository/UserRepository.java b/src/main/java/com/quickpick/ureca/user/repository/UserRepository.java deleted file mode 100644 index 50abb0e..0000000 --- a/src/main/java/com/quickpick/ureca/user/repository/UserRepository.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.quickpick.ureca.user.repository; - -public class UserRepository { -} diff --git a/src/main/java/com/quickpick/ureca/user/service/UserService.java b/src/main/java/com/quickpick/ureca/user/service/UserService.java deleted file mode 100644 index 972e2b1..0000000 --- a/src/main/java/com/quickpick/ureca/user/service/UserService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.quickpick.ureca.user.service; - -public class UserService { -} diff --git a/src/main/java/com/quickpick/ureca/user/v3/constants/Gender.java b/src/main/java/com/quickpick/ureca/user/v3/constants/Gender.java new file mode 100644 index 0000000..cf53b73 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/user/v3/constants/Gender.java @@ -0,0 +1,5 @@ +package com.quickpick.ureca.user.v3.constants; + +public enum Gender { + MALE, FEMALE +} diff --git a/src/main/java/com/quickpick/ureca/user/v3/controller/UserController.java b/src/main/java/com/quickpick/ureca/user/v3/controller/UserController.java new file mode 100644 index 0000000..3d4fae5 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/user/v3/controller/UserController.java @@ -0,0 +1,22 @@ +package com.quickpick.ureca.user.v3.controller; + +import com.quickpick.ureca.user.v3.dto.UserCreateRequest; +import com.quickpick.ureca.user.v3.service.UserService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RequestMapping("/v3/users") +@RestController +@RequiredArgsConstructor +public class UserController { + + private final UserService userService; + + @PostMapping + public void createUser(@RequestBody UserCreateRequest request) { + userService.save(request); + } +} diff --git a/src/main/java/com/quickpick/ureca/user/domain/User.java b/src/main/java/com/quickpick/ureca/user/v3/domain/User.java similarity index 62% rename from src/main/java/com/quickpick/ureca/user/domain/User.java rename to src/main/java/com/quickpick/ureca/user/v3/domain/User.java index 86eaaca..65406ec 100644 --- a/src/main/java/com/quickpick/ureca/user/domain/User.java +++ b/src/main/java/com/quickpick/ureca/user/v3/domain/User.java @@ -1,18 +1,19 @@ -package com.quickpick.ureca.user.domain; +package com.quickpick.ureca.user.v3.domain; import com.quickpick.ureca.common.domain.BaseEntity; -import com.quickpick.ureca.userticket.domain.UserTicket; +import com.quickpick.ureca.user.v3.constants.Gender; import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import java.util.ArrayList; -import java.util.List; - @Table @Entity @Getter @NoArgsConstructor +@AllArgsConstructor +@Builder public class User extends BaseEntity { @Id @@ -30,12 +31,9 @@ public class User extends BaseEntity { private String name; @Column(nullable = false) - private String age; + private int age; + @Enumerated(EnumType.STRING) @Column(nullable = false) - private String gender; - - @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) - private List userTickets = new ArrayList<>(); - + private Gender gender; } diff --git a/src/main/java/com/quickpick/ureca/user/v3/dto/UserCreateRequest.java b/src/main/java/com/quickpick/ureca/user/v3/dto/UserCreateRequest.java new file mode 100644 index 0000000..58a1655 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/user/v3/dto/UserCreateRequest.java @@ -0,0 +1,10 @@ +package com.quickpick.ureca.user.v3.dto; + +public record UserCreateRequest( + String id, + String password, + String name, + int age, + String gender +) { +} diff --git a/src/main/java/com/quickpick/ureca/user/v3/repository/UserRepository.java b/src/main/java/com/quickpick/ureca/user/v3/repository/UserRepository.java new file mode 100644 index 0000000..a11ed35 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/user/v3/repository/UserRepository.java @@ -0,0 +1,7 @@ +package com.quickpick.ureca.user.v3.repository; + +import com.quickpick.ureca.user.v3.domain.User; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository { +} diff --git a/src/main/java/com/quickpick/ureca/user/v3/service/UserService.java b/src/main/java/com/quickpick/ureca/user/v3/service/UserService.java new file mode 100644 index 0000000..2a4d460 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/user/v3/service/UserService.java @@ -0,0 +1,30 @@ +package com.quickpick.ureca.user.v3.service; + +import com.quickpick.ureca.user.v3.constants.Gender; +import com.quickpick.ureca.user.v3.domain.User; +import com.quickpick.ureca.user.v3.dto.UserCreateRequest; +import com.quickpick.ureca.user.v3.repository.UserRepository; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class UserService { + + private final UserRepository userRepository; + + @Transactional + public void save(final UserCreateRequest request) { + + User user = User.builder() + .id(request.id()) + .age(request.age()) + .name(request.name()) + .gender(Gender.valueOf(request.gender())) + .password(request.password()) + .build(); + + userRepository.save(user); + } +} diff --git a/src/main/java/com/quickpick/ureca/userticket/v3/domain/UserTicket.java b/src/main/java/com/quickpick/ureca/userticket/v3/domain/UserTicket.java new file mode 100644 index 0000000..240a7f1 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/userticket/v3/domain/UserTicket.java @@ -0,0 +1,25 @@ +package com.quickpick.ureca.userticket.v3.domain; + +import com.quickpick.ureca.common.domain.BaseEntity; +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Table(name = "user_ticket") +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class UserTicket extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "user_ticket_id") + private Long id; + + @Column(nullable = false) + private Long ticketId; + + @Column(nullable = false) + private Long userId; +} diff --git a/src/main/java/com/quickpick/ureca/userticket/v3/repository/UserTicketRepository.java b/src/main/java/com/quickpick/ureca/userticket/v3/repository/UserTicketRepository.java new file mode 100644 index 0000000..7b32044 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/userticket/v3/repository/UserTicketRepository.java @@ -0,0 +1,8 @@ +package com.quickpick.ureca.userticket.v3.repository; + +import com.quickpick.ureca.userticket.v3.domain.UserTicket; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserTicketRepository extends JpaRepository { + +} diff --git a/src/test/java/com/quickpick/ureca/UrecaApplicationTests.java b/src/test/java/com/quickpick/ureca/UrecaApplicationTests.java index 156f2fb..6f2ccff 100644 --- a/src/test/java/com/quickpick/ureca/UrecaApplicationTests.java +++ b/src/test/java/com/quickpick/ureca/UrecaApplicationTests.java @@ -1,13 +1,13 @@ -package com.quickpick.ureca; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class UrecaApplicationTests { - - @Test - void contextLoads() { - } - -} +//package com.quickpick.ureca; +// +//import org.junit.jupiter.api.Test; +//import org.springframework.boot.test.context.SpringBootTest; +// +//@SpringBootTest +//class UrecaApplicationTests { +// +// @Test +// void contextLoads() { +// } +// +//} From e7a6ec43765754378917112356a7adcf22a315cf Mon Sep 17 00:00:00 2001 From: sangyunpark99 Date: Wed, 7 May 2025 15:16:04 +0900 Subject: [PATCH 38/43] =?UTF-8?q?chore:=20V3=20Kafka=20=EB=B2=84=EC=A0=84?= =?UTF-8?q?=201=EB=B2=88=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=ED=99=98?= =?UTF-8?q?=EA=B2=BD=20=EA=B5=AC=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- infrastructure/docker-compose.yml | 62 +++++++++++++++++++ loadtest/load-test.jmx | 51 +++++++++++++++ loadtest/run-jmeter.sh | 15 +++++ .../quickpick/ureca/init/InitDataLoader.java | 6 +- 4 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 infrastructure/docker-compose.yml create mode 100644 loadtest/load-test.jmx create mode 100755 loadtest/run-jmeter.sh diff --git a/infrastructure/docker-compose.yml b/infrastructure/docker-compose.yml new file mode 100644 index 0000000..e005e0b --- /dev/null +++ b/infrastructure/docker-compose.yml @@ -0,0 +1,62 @@ +services: + mysql: + image: mysql:8 + container_name: mysql-container + ports: + - "3307:3306" + environment: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: test + MYSQL_USER: user + MYSQL_PASSWORD: userpass + volumes: + - mysql-data:/var/lib/mysql + + redis: + image: redis:7 + container_name: redis + ports: + - "6379:6379" + volumes: + - redis-data:/data + + kafka: + image: confluentinc/confluent-local:7.4.1 + container_name: kafka + ports: + - "9092:9092" + - "29092:29092" + - "9101:9101" + environment: + KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092 + KAFKA_LISTENERS: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://0.0.0.0:29092,CONTROLLER://localhost:29093 + KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER + KAFKA_PROCESS_ROLES: broker,controller + KAFKA_NODE_ID: 1 + KAFKA_CONTROLLER_QUORUM_VOTERS: 1@localhost:29093 + KAFKA_KRAFT_CLUSTER_ID: r4zt_wrqTRuT7W2NJsB_GA + KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT + KAFKA_CFG_INTER_BROKER_LISTENER_NAME: PLAINTEXT + KAFKA_CFG_LOG_DIRS: /tmp/kraft-combined-logs + KAFKA_NUM_PARTITIONS: 3 + volumes: + - kafka-data:/bitnami/kafka + + kafka-ui: + image: provectuslabs/kafka-ui:latest + container_name: kafka-ui + ports: + - "8000:8080" + environment: + KAFKA_CLUSTERS_0_NAME: local + KAFKA_CLUSTERS_0_BOOTSTRAP_SERVERS: kafka:9092 + DYNAMIC_CONFIG_ENABLED: true + AUTH_TYPE: DISABLED + MANAGEMENT_HEALTH_LDAP_ENABLED: false + depends_on: + - kafka + +volumes: + mysql-data: + redis-data: + kafka-data: \ No newline at end of file diff --git a/loadtest/load-test.jmx b/loadtest/load-test.jmx new file mode 100644 index 0000000..bc2da23 --- /dev/null +++ b/loadtest/load-test.jmx @@ -0,0 +1,51 @@ + + + + + + false + false + + + + + + continue + + false + 1 + + 10000 + 1 + false + + + + + + + true + userId + ${__Random(1,10000)} + = + true + + + + localhost + 8080 + http + /v3/tickets/1/purchase + POST + true + false + true + false + + + + + + + + \ No newline at end of file diff --git a/loadtest/run-jmeter.sh b/loadtest/run-jmeter.sh new file mode 100755 index 0000000..dc72791 --- /dev/null +++ b/loadtest/run-jmeter.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# 타임스탬프 생성 (예: 20240507_114523) +TIMESTAMP=$(date +%Y%m%d_%H%M%S) + +# 파일 경로 설정 +JMX_FILE="load-test.jmx" +JTL_FILE="result_${TIMESTAMP}.jtl" +REPORT_DIR="report_${TIMESTAMP}" + +# JMeter 테스트 실행 +echo "JMeter 테스트 실행 중..." +jmeter -n -t "$JMX_FILE" -l "$JTL_FILE" -e -o "$REPORT_DIR" + +echo "테스트 완료! 리포트 경로: $REPORT_DIR" \ No newline at end of file diff --git a/src/main/java/com/quickpick/ureca/init/InitDataLoader.java b/src/main/java/com/quickpick/ureca/init/InitDataLoader.java index 303b173..0e21c58 100644 --- a/src/main/java/com/quickpick/ureca/init/InitDataLoader.java +++ b/src/main/java/com/quickpick/ureca/init/InitDataLoader.java @@ -3,6 +3,7 @@ import com.quickpick.ureca.ticket.v3.domain.Ticket; import com.quickpick.ureca.ticket.v3.repository.RedisStockRepository; import com.quickpick.ureca.ticket.v3.repository.TicketRepository; +import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.boot.CommandLineRunner; import org.springframework.jdbc.core.JdbcTemplate; @@ -21,6 +22,7 @@ public class InitDataLoader implements CommandLineRunner { private final RedisStockRepository redisStockRepository; private final JdbcTemplate jdbcTemplate; + @Transactional @Override public void run(String... args) { String sql = "INSERT INTO user (id, name, age, gender, password) VALUES (?, ?, ?, ?, ?)"; @@ -43,12 +45,12 @@ public void run(String... args) { Ticket ticket = Ticket.builder() .name("ticket") - .quantity(1000L) + .quantity(3000L) .reserveTime(LocalDateTime.now()) .startDate(LocalDate.now()) .build(); Ticket saveTicket = ticketRepository.save(ticket); - redisStockRepository.setTicket(saveTicket.getId(), 1000L); + redisStockRepository.setTicket(saveTicket.getId(), 3000L); } } From c25e536ef548b58a2965b5eeae5bc72c2b9b09ca Mon Sep 17 00:00:00 2001 From: sangyunpark99 Date: Tue, 13 May 2025 11:07:29 +0900 Subject: [PATCH 39/43] =?UTF-8?q?chore:=20v3=ED=8F=B4=EB=8D=94=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- infrastructure/docker-compose.yml | 93 ++++++++++--------- infrastructure/kafka-topics.sh | 2 + loadtest/load-test.jmx | 51 ---------- loadtest/run-jmeter.sh | 15 --- .../com/quickpick/ureca/UrecaApplication.java | 4 +- .../ureca/user/v3/constants/Gender.java | 5 - .../v3/repository/UserTicketRepository.java | 8 -- .../domain => v3/common}/BaseEntity.java | 2 +- .../ureca/v3/config/KafkaConsumerConfig.java | 24 +++++ .../ureca/{ => v3}/init/InitDataLoader.java | 19 ++-- .../v3 => v3/reserve}/domain/Reserve.java | 4 +- .../reserve}/domain/ReserveStatus.java | 2 +- .../v3 => v3/ticket}/ExceptionHandlers.java | 2 +- .../controller/TicketControllerV3.java | 5 +- .../v3 => v3/ticket}/domain/Ticket.java | 4 +- .../ticket}/event/TicketPurchaseEvent.java | 2 +- .../ticket}/kafka/TicketEventConsumer.java | 30 +++--- .../ticket}/kafka/TicketEventProducer.java | 4 +- .../EventDuplicationRepository.java | 22 +++++ .../repository/RedisStockRepository.java | 2 +- .../ticket}/repository/ReserveRepository.java | 4 +- .../ticket}/repository/TicketRepository.java | 4 +- .../ticket}/service/TicketServiceV3.java | 25 +++-- .../ureca/v3/user/constants/Gender.java | 5 + .../user}/controller/UserController.java | 6 +- .../{user/v3 => v3/user}/domain/User.java | 12 +-- .../v3 => v3/user}/dto/UserCreateRequest.java | 2 +- .../user}/repository/UserRepository.java | 4 +- .../v3 => v3/user}/service/UserService.java | 11 +-- .../userticket}/domain/UserTicket.java | 4 +- .../repository/UserTicketRepository.java | 9 ++ .../ureca/UrecaApplicationTests.java | 26 +++--- 32 files changed, 206 insertions(+), 206 deletions(-) create mode 100755 infrastructure/kafka-topics.sh delete mode 100644 loadtest/load-test.jmx delete mode 100755 loadtest/run-jmeter.sh delete mode 100644 src/main/java/com/quickpick/ureca/user/v3/constants/Gender.java delete mode 100644 src/main/java/com/quickpick/ureca/userticket/v3/repository/UserTicketRepository.java rename src/main/java/com/quickpick/ureca/{common/domain => v3/common}/BaseEntity.java (91%) create mode 100644 src/main/java/com/quickpick/ureca/v3/config/KafkaConsumerConfig.java rename src/main/java/com/quickpick/ureca/{ => v3}/init/InitDataLoader.java (73%) rename src/main/java/com/quickpick/ureca/{reserve/v3 => v3/reserve}/domain/Reserve.java (84%) rename src/main/java/com/quickpick/ureca/{reserve/v3 => v3/reserve}/domain/ReserveStatus.java (51%) rename src/main/java/com/quickpick/ureca/{ticket/v3 => v3/ticket}/ExceptionHandlers.java (92%) rename src/main/java/com/quickpick/ureca/{ticket/v3 => v3/ticket}/controller/TicketControllerV3.java (80%) rename src/main/java/com/quickpick/ureca/{ticket/v3 => v3/ticket}/domain/Ticket.java (86%) rename src/main/java/com/quickpick/ureca/{ticket/v3 => v3/ticket}/event/TicketPurchaseEvent.java (88%) rename src/main/java/com/quickpick/ureca/{ticket/v3 => v3/ticket}/kafka/TicketEventConsumer.java (58%) rename src/main/java/com/quickpick/ureca/{ticket/v3 => v3/ticket}/kafka/TicketEventProducer.java (81%) create mode 100644 src/main/java/com/quickpick/ureca/v3/ticket/repository/EventDuplicationRepository.java rename src/main/java/com/quickpick/ureca/{ticket/v3 => v3/ticket}/repository/RedisStockRepository.java (97%) rename src/main/java/com/quickpick/ureca/{ticket/v3 => v3/ticket}/repository/ReserveRepository.java (57%) rename src/main/java/com/quickpick/ureca/{ticket/v3 => v3/ticket}/repository/TicketRepository.java (83%) rename src/main/java/com/quickpick/ureca/{ticket/v3 => v3/ticket}/service/TicketServiceV3.java (50%) create mode 100644 src/main/java/com/quickpick/ureca/v3/user/constants/Gender.java rename src/main/java/com/quickpick/ureca/{user/v3 => v3/user}/controller/UserController.java (77%) rename src/main/java/com/quickpick/ureca/{user/v3 => v3/user}/domain/User.java (72%) rename src/main/java/com/quickpick/ureca/{user/v3 => v3/user}/dto/UserCreateRequest.java (77%) rename src/main/java/com/quickpick/ureca/{user/v3 => v3/user}/repository/UserRepository.java (58%) rename src/main/java/com/quickpick/ureca/{user/v3 => v3/user}/service/UserService.java (66%) rename src/main/java/com/quickpick/ureca/{userticket/v3 => v3/userticket}/domain/UserTicket.java (81%) create mode 100644 src/main/java/com/quickpick/ureca/v3/userticket/repository/UserTicketRepository.java diff --git a/infrastructure/docker-compose.yml b/infrastructure/docker-compose.yml index e005e0b..4213d30 100644 --- a/infrastructure/docker-compose.yml +++ b/infrastructure/docker-compose.yml @@ -1,46 +1,30 @@ services: - mysql: - image: mysql:8 - container_name: mysql-container + zookeeper: + image: confluentinc/cp-zookeeper:7.4.1 + container_name: zookeeper ports: - - "3307:3306" + - "2181:2181" environment: - MYSQL_ROOT_PASSWORD: root - MYSQL_DATABASE: test - MYSQL_USER: user - MYSQL_PASSWORD: userpass - volumes: - - mysql-data:/var/lib/mysql + ZOOKEEPER_CLIENT_PORT: 2181 + ZOOKEEPER_TICK_TIME: 2000 - redis: - image: redis:7 - container_name: redis - ports: - - "6379:6379" - volumes: - - redis-data:/data - - kafka: - image: confluentinc/confluent-local:7.4.1 - container_name: kafka + kafka-1: + image: confluentinc/cp-kafka:7.4.1 + container_name: kafka-1 + depends_on: + - zookeeper ports: - "9092:9092" - - "29092:29092" - - "9101:9101" + - "19092:19092" environment: - KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092 - KAFKA_LISTENERS: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://0.0.0.0:29092,CONTROLLER://localhost:29093 - KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER - KAFKA_PROCESS_ROLES: broker,controller - KAFKA_NODE_ID: 1 - KAFKA_CONTROLLER_QUORUM_VOTERS: 1@localhost:29093 - KAFKA_KRAFT_CLUSTER_ID: r4zt_wrqTRuT7W2NJsB_GA - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT - KAFKA_CFG_INTER_BROKER_LISTENER_NAME: PLAINTEXT - KAFKA_CFG_LOG_DIRS: /tmp/kraft-combined-logs - KAFKA_NUM_PARTITIONS: 3 - volumes: - - kafka-data:/bitnami/kafka + KAFKA_BROKER_ID: 1 + KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 + KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-1:9092,PLAINTEXT_HOST://localhost:19092 + KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,PLAINTEXT_HOST://0.0.0.0:19092 + KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT + KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT + KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 + KAFKA_AUTO_CREATE_TOPICS_ENABLE: true kafka-ui: image: provectuslabs/kafka-ui:latest @@ -48,15 +32,38 @@ services: ports: - "8000:8080" environment: - KAFKA_CLUSTERS_0_NAME: local - KAFKA_CLUSTERS_0_BOOTSTRAP_SERVERS: kafka:9092 + KAFKA_CLUSTERS_0_NAME: local-cluster + KAFKA_CLUSTERS_0_BOOTSTRAP_SERVERS: kafka-1:9092 DYNAMIC_CONFIG_ENABLED: true - AUTH_TYPE: DISABLED - MANAGEMENT_HEALTH_LDAP_ENABLED: false depends_on: - - kafka + - kafka-1 + + redis: + image: redis:7 + container_name: redis + ports: + - "6379:6379" + volumes: + - redis-data:/data + + mysql: + image: mysql:8 + container_name: mysql-container + ports: + - "3307:3306" + environment: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: test + MYSQL_USER: user + MYSQL_PASSWORD: userpass + volumes: + - mysql-data:/var/lib/mysql + +networks: + ngrinder-net: + driver: bridge volumes: - mysql-data: + kafka-data: redis-data: - kafka-data: \ No newline at end of file + mysql-data: \ No newline at end of file diff --git a/infrastructure/kafka-topics.sh b/infrastructure/kafka-topics.sh new file mode 100755 index 0000000..5c2493d --- /dev/null +++ b/infrastructure/kafka-topics.sh @@ -0,0 +1,2 @@ +kafka-topics.sh --bootstrap-server localhost:9092 --delete --topic ticket.purchase +kafka-topics.sh --bootstrap-server localhost:9092 --create --topic ticket.purchase --partitions 3 \ No newline at end of file diff --git a/loadtest/load-test.jmx b/loadtest/load-test.jmx deleted file mode 100644 index bc2da23..0000000 --- a/loadtest/load-test.jmx +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - false - false - - - - - - continue - - false - 1 - - 10000 - 1 - false - - - - - - - true - userId - ${__Random(1,10000)} - = - true - - - - localhost - 8080 - http - /v3/tickets/1/purchase - POST - true - false - true - false - - - - - - - - \ No newline at end of file diff --git a/loadtest/run-jmeter.sh b/loadtest/run-jmeter.sh deleted file mode 100755 index dc72791..0000000 --- a/loadtest/run-jmeter.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -# 타임스탬프 생성 (예: 20240507_114523) -TIMESTAMP=$(date +%Y%m%d_%H%M%S) - -# 파일 경로 설정 -JMX_FILE="load-test.jmx" -JTL_FILE="result_${TIMESTAMP}.jtl" -REPORT_DIR="report_${TIMESTAMP}" - -# JMeter 테스트 실행 -echo "JMeter 테스트 실행 중..." -jmeter -n -t "$JMX_FILE" -l "$JTL_FILE" -e -o "$REPORT_DIR" - -echo "테스트 완료! 리포트 경로: $REPORT_DIR" \ No newline at end of file diff --git a/src/main/java/com/quickpick/ureca/UrecaApplication.java b/src/main/java/com/quickpick/ureca/UrecaApplication.java index 8be528e..14add35 100644 --- a/src/main/java/com/quickpick/ureca/UrecaApplication.java +++ b/src/main/java/com/quickpick/ureca/UrecaApplication.java @@ -9,9 +9,7 @@ @EnableJpaAuditing @EnableScheduling public class UrecaApplication { - public static void main(String[] args) { SpringApplication.run(UrecaApplication.class, args); } - -} +} \ No newline at end of file diff --git a/src/main/java/com/quickpick/ureca/user/v3/constants/Gender.java b/src/main/java/com/quickpick/ureca/user/v3/constants/Gender.java deleted file mode 100644 index cf53b73..0000000 --- a/src/main/java/com/quickpick/ureca/user/v3/constants/Gender.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.quickpick.ureca.user.v3.constants; - -public enum Gender { - MALE, FEMALE -} diff --git a/src/main/java/com/quickpick/ureca/userticket/v3/repository/UserTicketRepository.java b/src/main/java/com/quickpick/ureca/userticket/v3/repository/UserTicketRepository.java deleted file mode 100644 index 7b32044..0000000 --- a/src/main/java/com/quickpick/ureca/userticket/v3/repository/UserTicketRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.quickpick.ureca.userticket.v3.repository; - -import com.quickpick.ureca.userticket.v3.domain.UserTicket; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface UserTicketRepository extends JpaRepository { - -} diff --git a/src/main/java/com/quickpick/ureca/common/domain/BaseEntity.java b/src/main/java/com/quickpick/ureca/v3/common/BaseEntity.java similarity index 91% rename from src/main/java/com/quickpick/ureca/common/domain/BaseEntity.java rename to src/main/java/com/quickpick/ureca/v3/common/BaseEntity.java index e4ac893..917e240 100644 --- a/src/main/java/com/quickpick/ureca/common/domain/BaseEntity.java +++ b/src/main/java/com/quickpick/ureca/v3/common/BaseEntity.java @@ -1,4 +1,4 @@ -package com.quickpick.ureca.common.domain; +package com.quickpick.ureca.v3.common; import jakarta.persistence.Column; import jakarta.persistence.EntityListeners; diff --git a/src/main/java/com/quickpick/ureca/v3/config/KafkaConsumerConfig.java b/src/main/java/com/quickpick/ureca/v3/config/KafkaConsumerConfig.java new file mode 100644 index 0000000..0a0fcc7 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/v3/config/KafkaConsumerConfig.java @@ -0,0 +1,24 @@ +package com.quickpick.ureca.v3.config; + +import com.quickpick.ureca.v3.ticket.event.TicketPurchaseEvent; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; +import org.springframework.kafka.core.ConsumerFactory; + +@Configuration +public class KafkaConsumerConfig { + + @Bean + public ConcurrentKafkaListenerContainerFactory batchFactory( + ConsumerFactory consumerFactory) { + + ConcurrentKafkaListenerContainerFactory factory = + new ConcurrentKafkaListenerContainerFactory<>(); + + factory.setConsumerFactory(consumerFactory); + factory.setBatchListener(true); // 핵심 + factory.setConcurrency(3); + return factory; + } +} diff --git a/src/main/java/com/quickpick/ureca/init/InitDataLoader.java b/src/main/java/com/quickpick/ureca/v3/init/InitDataLoader.java similarity index 73% rename from src/main/java/com/quickpick/ureca/init/InitDataLoader.java rename to src/main/java/com/quickpick/ureca/v3/init/InitDataLoader.java index 0e21c58..31d65af 100644 --- a/src/main/java/com/quickpick/ureca/init/InitDataLoader.java +++ b/src/main/java/com/quickpick/ureca/v3/init/InitDataLoader.java @@ -1,8 +1,8 @@ -package com.quickpick.ureca.init; +package com.quickpick.ureca.v3.init; -import com.quickpick.ureca.ticket.v3.domain.Ticket; -import com.quickpick.ureca.ticket.v3.repository.RedisStockRepository; -import com.quickpick.ureca.ticket.v3.repository.TicketRepository; +import com.quickpick.ureca.v3.ticket.domain.Ticket; +import com.quickpick.ureca.v3.ticket.repository.RedisStockRepository; +import com.quickpick.ureca.v3.ticket.repository.TicketRepository; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.boot.CommandLineRunner; @@ -25,17 +25,18 @@ public class InitDataLoader implements CommandLineRunner { @Transactional @Override public void run(String... args) { - String sql = "INSERT INTO user (id, name, age, gender, password) VALUES (?, ?, ?, ?, ?)"; + String sql = "INSERT INTO user (user_id, name, age, gender, password) VALUES (?, ?, ?, ?, ?)"; List batchArgs = new ArrayList<>(); - for (long i = 1; i <= 100_000; i++) { + for (long i = 1; i <= 10000; i++) { batchArgs.add(new Object[]{ + i, "abc" + i, - "user" + i, - (int) i, - "MALE", // enum은 문자열로 저장한다고 가정 + i+20, + "MALE", "password" + i + }); } diff --git a/src/main/java/com/quickpick/ureca/reserve/v3/domain/Reserve.java b/src/main/java/com/quickpick/ureca/v3/reserve/domain/Reserve.java similarity index 84% rename from src/main/java/com/quickpick/ureca/reserve/v3/domain/Reserve.java rename to src/main/java/com/quickpick/ureca/v3/reserve/domain/Reserve.java index e0506fd..0a45c9a 100644 --- a/src/main/java/com/quickpick/ureca/reserve/v3/domain/Reserve.java +++ b/src/main/java/com/quickpick/ureca/v3/reserve/domain/Reserve.java @@ -1,6 +1,6 @@ -package com.quickpick.ureca.reserve.v3.domain; +package com.quickpick.ureca.v3.reserve.domain; -import com.quickpick.ureca.common.domain.BaseEntity; +import com.quickpick.ureca.v3.common.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; diff --git a/src/main/java/com/quickpick/ureca/reserve/v3/domain/ReserveStatus.java b/src/main/java/com/quickpick/ureca/v3/reserve/domain/ReserveStatus.java similarity index 51% rename from src/main/java/com/quickpick/ureca/reserve/v3/domain/ReserveStatus.java rename to src/main/java/com/quickpick/ureca/v3/reserve/domain/ReserveStatus.java index 3aa91f4..e342fbb 100644 --- a/src/main/java/com/quickpick/ureca/reserve/v3/domain/ReserveStatus.java +++ b/src/main/java/com/quickpick/ureca/v3/reserve/domain/ReserveStatus.java @@ -1,4 +1,4 @@ -package com.quickpick.ureca.reserve.v3.domain; +package com.quickpick.ureca.v3.reserve.domain; public enum ReserveStatus { SUCCESS, FAIL diff --git a/src/main/java/com/quickpick/ureca/ticket/v3/ExceptionHandlers.java b/src/main/java/com/quickpick/ureca/v3/ticket/ExceptionHandlers.java similarity index 92% rename from src/main/java/com/quickpick/ureca/ticket/v3/ExceptionHandlers.java rename to src/main/java/com/quickpick/ureca/v3/ticket/ExceptionHandlers.java index 48d9fbf..b171ff0 100644 --- a/src/main/java/com/quickpick/ureca/ticket/v3/ExceptionHandlers.java +++ b/src/main/java/com/quickpick/ureca/v3/ticket/ExceptionHandlers.java @@ -1,4 +1,4 @@ -package com.quickpick.ureca.ticket.v3; +package com.quickpick.ureca.v3.ticket; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/src/main/java/com/quickpick/ureca/ticket/v3/controller/TicketControllerV3.java b/src/main/java/com/quickpick/ureca/v3/ticket/controller/TicketControllerV3.java similarity index 80% rename from src/main/java/com/quickpick/ureca/ticket/v3/controller/TicketControllerV3.java rename to src/main/java/com/quickpick/ureca/v3/ticket/controller/TicketControllerV3.java index 20aa353..16462c9 100644 --- a/src/main/java/com/quickpick/ureca/ticket/v3/controller/TicketControllerV3.java +++ b/src/main/java/com/quickpick/ureca/v3/ticket/controller/TicketControllerV3.java @@ -1,6 +1,6 @@ -package com.quickpick.ureca.ticket.v3.controller; +package com.quickpick.ureca.v3.ticket.controller; -import com.quickpick.ureca.ticket.v3.service.TicketServiceV3; +import com.quickpick.ureca.v3.ticket.service.TicketServiceV3; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; @@ -16,5 +16,4 @@ public String purchaseTicket(@PathVariable Long ticketId, @RequestParam Long use ticketServiceV3.purchaseTicket(ticketId, userId, 1L); return "success"; } - } diff --git a/src/main/java/com/quickpick/ureca/ticket/v3/domain/Ticket.java b/src/main/java/com/quickpick/ureca/v3/ticket/domain/Ticket.java similarity index 86% rename from src/main/java/com/quickpick/ureca/ticket/v3/domain/Ticket.java rename to src/main/java/com/quickpick/ureca/v3/ticket/domain/Ticket.java index 54b04ae..80f5b5e 100644 --- a/src/main/java/com/quickpick/ureca/ticket/v3/domain/Ticket.java +++ b/src/main/java/com/quickpick/ureca/v3/ticket/domain/Ticket.java @@ -1,6 +1,6 @@ -package com.quickpick.ureca.ticket.v3.domain; +package com.quickpick.ureca.v3.ticket.domain; -import com.quickpick.ureca.common.domain.BaseEntity; +import com.quickpick.ureca.v3.common.BaseEntity; import jakarta.persistence.*; import lombok.*; diff --git a/src/main/java/com/quickpick/ureca/ticket/v3/event/TicketPurchaseEvent.java b/src/main/java/com/quickpick/ureca/v3/ticket/event/TicketPurchaseEvent.java similarity index 88% rename from src/main/java/com/quickpick/ureca/ticket/v3/event/TicketPurchaseEvent.java rename to src/main/java/com/quickpick/ureca/v3/ticket/event/TicketPurchaseEvent.java index 9517800..bfad829 100644 --- a/src/main/java/com/quickpick/ureca/ticket/v3/event/TicketPurchaseEvent.java +++ b/src/main/java/com/quickpick/ureca/v3/ticket/event/TicketPurchaseEvent.java @@ -1,4 +1,4 @@ -package com.quickpick.ureca.ticket.v3.event; +package com.quickpick.ureca.v3.ticket.event; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/quickpick/ureca/ticket/v3/kafka/TicketEventConsumer.java b/src/main/java/com/quickpick/ureca/v3/ticket/kafka/TicketEventConsumer.java similarity index 58% rename from src/main/java/com/quickpick/ureca/ticket/v3/kafka/TicketEventConsumer.java rename to src/main/java/com/quickpick/ureca/v3/ticket/kafka/TicketEventConsumer.java index ac13142..6cb9001 100644 --- a/src/main/java/com/quickpick/ureca/ticket/v3/kafka/TicketEventConsumer.java +++ b/src/main/java/com/quickpick/ureca/v3/ticket/kafka/TicketEventConsumer.java @@ -1,15 +1,17 @@ -package com.quickpick.ureca.ticket.v3.kafka; - -import com.quickpick.ureca.reserve.v3.domain.Reserve; -import com.quickpick.ureca.reserve.v3.domain.ReserveStatus; -import com.quickpick.ureca.ticket.v3.event.TicketPurchaseEvent; -import com.quickpick.ureca.ticket.v3.repository.ReserveRepository; -import com.quickpick.ureca.ticket.v3.repository.TicketRepository; -import com.quickpick.ureca.userticket.v3.domain.UserTicket; -import com.quickpick.ureca.userticket.v3.repository.UserTicketRepository; +package com.quickpick.ureca.v3.ticket.kafka; + +import com.quickpick.ureca.v3.reserve.domain.Reserve; +import com.quickpick.ureca.v3.reserve.domain.ReserveStatus; +import com.quickpick.ureca.v3.ticket.event.TicketPurchaseEvent; +import com.quickpick.ureca.v3.ticket.repository.ReserveRepository; +import com.quickpick.ureca.v3.ticket.repository.TicketRepository; +import com.quickpick.ureca.v3.userticket.domain.UserTicket; +import com.quickpick.ureca.v3.userticket.repository.UserTicketRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.kafka.support.KafkaHeaders; +import org.springframework.messaging.handler.annotation.Header; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @@ -22,10 +24,15 @@ public class TicketEventConsumer { private final UserTicketRepository userTicketRepository; private final ReserveRepository reserveRepository; - @KafkaListener(topics = "ticket.purchase", groupId = "ticket-service") @Transactional - public void consume(final TicketPurchaseEvent event) { + @KafkaListener(topics = "ticket.purchase", groupId = "ticket-service", concurrency = "3") + public void consume(final TicketPurchaseEvent event, @Header(KafkaHeaders.RECEIVED_PARTITION) int partition) { + log.info("ticker.purchased 이벤트 수신, 수신한 아이디 : {}", event.getUserId()); + log.info("Consumed message from partition [{}] by thread [{}], userId: {}", + partition, + Thread.currentThread().getName(), + event.getUserId()); int result = ticketRepository.decreaseStock(event.getTicketId(), 1); if(result == 0) { @@ -38,6 +45,7 @@ public void consume(final TicketPurchaseEvent event) { .build(); userTicketRepository.save(userTicket); + Reserve reserve = Reserve.builder() .userId(event.getUserId()) .status(ReserveStatus.SUCCESS) diff --git a/src/main/java/com/quickpick/ureca/ticket/v3/kafka/TicketEventProducer.java b/src/main/java/com/quickpick/ureca/v3/ticket/kafka/TicketEventProducer.java similarity index 81% rename from src/main/java/com/quickpick/ureca/ticket/v3/kafka/TicketEventProducer.java rename to src/main/java/com/quickpick/ureca/v3/ticket/kafka/TicketEventProducer.java index 45e11ec..dbaddc2 100644 --- a/src/main/java/com/quickpick/ureca/ticket/v3/kafka/TicketEventProducer.java +++ b/src/main/java/com/quickpick/ureca/v3/ticket/kafka/TicketEventProducer.java @@ -1,6 +1,6 @@ -package com.quickpick.ureca.ticket.v3.kafka; +package com.quickpick.ureca.v3.ticket.kafka; -import com.quickpick.ureca.ticket.v3.event.TicketPurchaseEvent; +import com.quickpick.ureca.v3.ticket.event.TicketPurchaseEvent; import lombok.RequiredArgsConstructor; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.stereotype.Component; diff --git a/src/main/java/com/quickpick/ureca/v3/ticket/repository/EventDuplicationRepository.java b/src/main/java/com/quickpick/ureca/v3/ticket/repository/EventDuplicationRepository.java new file mode 100644 index 0000000..e1e19f5 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/v3/ticket/repository/EventDuplicationRepository.java @@ -0,0 +1,22 @@ +package com.quickpick.ureca.v3.ticket.repository; + + +import lombok.RequiredArgsConstructor; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Repository; + +import java.time.Duration; + +@Repository +@RequiredArgsConstructor +public class EventDuplicationRepository { + + private final RedisTemplate redisTemplate; + private static final String KEY_PREFIX = "processed:"; + + public boolean markIfNotProcessed(final Long userId) { + String key = KEY_PREFIX + userId; + return Boolean.TRUE.equals(redisTemplate.opsForValue() + .setIfAbsent(key, "1", Duration.ofMinutes(5))); + } +} diff --git a/src/main/java/com/quickpick/ureca/ticket/v3/repository/RedisStockRepository.java b/src/main/java/com/quickpick/ureca/v3/ticket/repository/RedisStockRepository.java similarity index 97% rename from src/main/java/com/quickpick/ureca/ticket/v3/repository/RedisStockRepository.java rename to src/main/java/com/quickpick/ureca/v3/ticket/repository/RedisStockRepository.java index 183f4e1..f894688 100644 --- a/src/main/java/com/quickpick/ureca/ticket/v3/repository/RedisStockRepository.java +++ b/src/main/java/com/quickpick/ureca/v3/ticket/repository/RedisStockRepository.java @@ -1,4 +1,4 @@ -package com.quickpick.ureca.ticket.v3.repository; +package com.quickpick.ureca.v3.ticket.repository; import lombok.RequiredArgsConstructor; import org.springframework.data.redis.core.RedisTemplate; diff --git a/src/main/java/com/quickpick/ureca/ticket/v3/repository/ReserveRepository.java b/src/main/java/com/quickpick/ureca/v3/ticket/repository/ReserveRepository.java similarity index 57% rename from src/main/java/com/quickpick/ureca/ticket/v3/repository/ReserveRepository.java rename to src/main/java/com/quickpick/ureca/v3/ticket/repository/ReserveRepository.java index f3a5444..fd18490 100644 --- a/src/main/java/com/quickpick/ureca/ticket/v3/repository/ReserveRepository.java +++ b/src/main/java/com/quickpick/ureca/v3/ticket/repository/ReserveRepository.java @@ -1,6 +1,6 @@ -package com.quickpick.ureca.ticket.v3.repository; +package com.quickpick.ureca.v3.ticket.repository; -import com.quickpick.ureca.reserve.v3.domain.Reserve; +import com.quickpick.ureca.v3.reserve.domain.Reserve; import org.springframework.data.jpa.repository.JpaRepository; public interface ReserveRepository extends JpaRepository { diff --git a/src/main/java/com/quickpick/ureca/ticket/v3/repository/TicketRepository.java b/src/main/java/com/quickpick/ureca/v3/ticket/repository/TicketRepository.java similarity index 83% rename from src/main/java/com/quickpick/ureca/ticket/v3/repository/TicketRepository.java rename to src/main/java/com/quickpick/ureca/v3/ticket/repository/TicketRepository.java index ecfc2b7..c31a63f 100644 --- a/src/main/java/com/quickpick/ureca/ticket/v3/repository/TicketRepository.java +++ b/src/main/java/com/quickpick/ureca/v3/ticket/repository/TicketRepository.java @@ -1,6 +1,6 @@ -package com.quickpick.ureca.ticket.v3.repository; +package com.quickpick.ureca.v3.ticket.repository; -import com.quickpick.ureca.ticket.v3.domain.Ticket; +import com.quickpick.ureca.v3.ticket.domain.Ticket; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; diff --git a/src/main/java/com/quickpick/ureca/ticket/v3/service/TicketServiceV3.java b/src/main/java/com/quickpick/ureca/v3/ticket/service/TicketServiceV3.java similarity index 50% rename from src/main/java/com/quickpick/ureca/ticket/v3/service/TicketServiceV3.java rename to src/main/java/com/quickpick/ureca/v3/ticket/service/TicketServiceV3.java index dcde3d8..ed4e54b 100644 --- a/src/main/java/com/quickpick/ureca/ticket/v3/service/TicketServiceV3.java +++ b/src/main/java/com/quickpick/ureca/v3/ticket/service/TicketServiceV3.java @@ -1,14 +1,17 @@ -package com.quickpick.ureca.ticket.v3.service; +package com.quickpick.ureca.v3.ticket.service; -import com.quickpick.ureca.ticket.v3.event.TicketPurchaseEvent; -import com.quickpick.ureca.ticket.v3.kafka.TicketEventProducer; -import com.quickpick.ureca.ticket.v3.repository.RedisStockRepository; -import com.quickpick.ureca.user.v3.repository.UserRepository; +import com.quickpick.ureca.v3.ticket.event.TicketPurchaseEvent; +import com.quickpick.ureca.v3.ticket.kafka.TicketEventProducer; +import com.quickpick.ureca.v3.ticket.repository.RedisStockRepository; +import com.quickpick.ureca.v3.user.repository.UserRepository; +import com.quickpick.ureca.v3.userticket.repository.UserTicketRepository; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.util.UUID; +@Slf4j @Service @RequiredArgsConstructor public class TicketServiceV3 { @@ -16,20 +19,26 @@ public class TicketServiceV3 { private final UserRepository userRepository; private final RedisStockRepository redisStockRepository; private final TicketEventProducer ticketEventProducer; + private final UserTicketRepository userTicketRepository; public void purchaseTicket(final Long ticketId, final Long userId, final Long quantity) { if(!userRepository.existsById(userId)) { + log.error("존재하지 않는 사용자입니다."); throw new RuntimeException("존재하지 않는 사용자입니다."); } - Long result = redisStockRepository.decrease(ticketId, quantity); + if(userTicketRepository.existsByUserId(userId)) { + log.error("이미 예약을 성공한 사용자입니다."); + throw new RuntimeException("이미 예약을 성공한 사용자입니다."); + } + + final Long result = redisStockRepository.decrease(ticketId, quantity); if (result == -1L) { throw new RuntimeException("티켓이 전부 소진되었습니다."); } - // 티켓 전부 소진시 메시지 발행 - TicketPurchaseEvent ticketPurchaseEvent = TicketPurchaseEvent.builder() + final TicketPurchaseEvent ticketPurchaseEvent = TicketPurchaseEvent.builder() .uuid(UUID.randomUUID().toString()) .ticketId(ticketId) .userId(userId) diff --git a/src/main/java/com/quickpick/ureca/v3/user/constants/Gender.java b/src/main/java/com/quickpick/ureca/v3/user/constants/Gender.java new file mode 100644 index 0000000..6d6567f --- /dev/null +++ b/src/main/java/com/quickpick/ureca/v3/user/constants/Gender.java @@ -0,0 +1,5 @@ +package com.quickpick.ureca.v3.user.constants; + +public enum Gender { + MALE, FEMALE +} diff --git a/src/main/java/com/quickpick/ureca/user/v3/controller/UserController.java b/src/main/java/com/quickpick/ureca/v3/user/controller/UserController.java similarity index 77% rename from src/main/java/com/quickpick/ureca/user/v3/controller/UserController.java rename to src/main/java/com/quickpick/ureca/v3/user/controller/UserController.java index 3d4fae5..9ac011d 100644 --- a/src/main/java/com/quickpick/ureca/user/v3/controller/UserController.java +++ b/src/main/java/com/quickpick/ureca/v3/user/controller/UserController.java @@ -1,7 +1,7 @@ -package com.quickpick.ureca.user.v3.controller; +package com.quickpick.ureca.v3.user.controller; -import com.quickpick.ureca.user.v3.dto.UserCreateRequest; -import com.quickpick.ureca.user.v3.service.UserService; +import com.quickpick.ureca.v3.user.dto.UserCreateRequest; +import com.quickpick.ureca.v3.user.service.UserService; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; diff --git a/src/main/java/com/quickpick/ureca/user/v3/domain/User.java b/src/main/java/com/quickpick/ureca/v3/user/domain/User.java similarity index 72% rename from src/main/java/com/quickpick/ureca/user/v3/domain/User.java rename to src/main/java/com/quickpick/ureca/v3/user/domain/User.java index 65406ec..7a66bd2 100644 --- a/src/main/java/com/quickpick/ureca/user/v3/domain/User.java +++ b/src/main/java/com/quickpick/ureca/v3/user/domain/User.java @@ -1,7 +1,7 @@ -package com.quickpick.ureca.user.v3.domain; +package com.quickpick.ureca.v3.user.domain; -import com.quickpick.ureca.common.domain.BaseEntity; -import com.quickpick.ureca.user.v3.constants.Gender; +import com.quickpick.ureca.v3.common.BaseEntity; +import com.quickpick.ureca.v3.user.constants.Gender; import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; @@ -18,18 +18,14 @@ public class User extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "user_id") private Long userId; @Column(nullable = false) - private String id; + private String name; @Column(nullable = false) private String password; - @Column(nullable = false) - private String name; - @Column(nullable = false) private int age; diff --git a/src/main/java/com/quickpick/ureca/user/v3/dto/UserCreateRequest.java b/src/main/java/com/quickpick/ureca/v3/user/dto/UserCreateRequest.java similarity index 77% rename from src/main/java/com/quickpick/ureca/user/v3/dto/UserCreateRequest.java rename to src/main/java/com/quickpick/ureca/v3/user/dto/UserCreateRequest.java index 58a1655..c368b51 100644 --- a/src/main/java/com/quickpick/ureca/user/v3/dto/UserCreateRequest.java +++ b/src/main/java/com/quickpick/ureca/v3/user/dto/UserCreateRequest.java @@ -1,4 +1,4 @@ -package com.quickpick.ureca.user.v3.dto; +package com.quickpick.ureca.v3.user.dto; public record UserCreateRequest( String id, diff --git a/src/main/java/com/quickpick/ureca/user/v3/repository/UserRepository.java b/src/main/java/com/quickpick/ureca/v3/user/repository/UserRepository.java similarity index 58% rename from src/main/java/com/quickpick/ureca/user/v3/repository/UserRepository.java rename to src/main/java/com/quickpick/ureca/v3/user/repository/UserRepository.java index a11ed35..3ed7f86 100644 --- a/src/main/java/com/quickpick/ureca/user/v3/repository/UserRepository.java +++ b/src/main/java/com/quickpick/ureca/v3/user/repository/UserRepository.java @@ -1,6 +1,6 @@ -package com.quickpick.ureca.user.v3.repository; +package com.quickpick.ureca.v3.user.repository; -import com.quickpick.ureca.user.v3.domain.User; +import com.quickpick.ureca.v3.user.domain.User; import org.springframework.data.jpa.repository.JpaRepository; public interface UserRepository extends JpaRepository { diff --git a/src/main/java/com/quickpick/ureca/user/v3/service/UserService.java b/src/main/java/com/quickpick/ureca/v3/user/service/UserService.java similarity index 66% rename from src/main/java/com/quickpick/ureca/user/v3/service/UserService.java rename to src/main/java/com/quickpick/ureca/v3/user/service/UserService.java index 2a4d460..97c3a7f 100644 --- a/src/main/java/com/quickpick/ureca/user/v3/service/UserService.java +++ b/src/main/java/com/quickpick/ureca/v3/user/service/UserService.java @@ -1,9 +1,9 @@ -package com.quickpick.ureca.user.v3.service; +package com.quickpick.ureca.v3.user.service; -import com.quickpick.ureca.user.v3.constants.Gender; -import com.quickpick.ureca.user.v3.domain.User; -import com.quickpick.ureca.user.v3.dto.UserCreateRequest; -import com.quickpick.ureca.user.v3.repository.UserRepository; +import com.quickpick.ureca.v3.user.constants.Gender; +import com.quickpick.ureca.v3.user.domain.User; +import com.quickpick.ureca.v3.user.dto.UserCreateRequest; +import com.quickpick.ureca.v3.user.repository.UserRepository; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -18,7 +18,6 @@ public class UserService { public void save(final UserCreateRequest request) { User user = User.builder() - .id(request.id()) .age(request.age()) .name(request.name()) .gender(Gender.valueOf(request.gender())) diff --git a/src/main/java/com/quickpick/ureca/userticket/v3/domain/UserTicket.java b/src/main/java/com/quickpick/ureca/v3/userticket/domain/UserTicket.java similarity index 81% rename from src/main/java/com/quickpick/ureca/userticket/v3/domain/UserTicket.java rename to src/main/java/com/quickpick/ureca/v3/userticket/domain/UserTicket.java index 240a7f1..4069bfb 100644 --- a/src/main/java/com/quickpick/ureca/userticket/v3/domain/UserTicket.java +++ b/src/main/java/com/quickpick/ureca/v3/userticket/domain/UserTicket.java @@ -1,6 +1,6 @@ -package com.quickpick.ureca.userticket.v3.domain; +package com.quickpick.ureca.v3.userticket.domain; -import com.quickpick.ureca.common.domain.BaseEntity; +import com.quickpick.ureca.v3.common.BaseEntity; import jakarta.persistence.*; import lombok.*; diff --git a/src/main/java/com/quickpick/ureca/v3/userticket/repository/UserTicketRepository.java b/src/main/java/com/quickpick/ureca/v3/userticket/repository/UserTicketRepository.java new file mode 100644 index 0000000..8a40e43 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/v3/userticket/repository/UserTicketRepository.java @@ -0,0 +1,9 @@ +package com.quickpick.ureca.v3.userticket.repository; + +import com.quickpick.ureca.v3.userticket.domain.UserTicket; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserTicketRepository extends JpaRepository { + + boolean existsByUserId(Long userId); +} diff --git a/src/test/java/com/quickpick/ureca/UrecaApplicationTests.java b/src/test/java/com/quickpick/ureca/UrecaApplicationTests.java index 6f2ccff..156f2fb 100644 --- a/src/test/java/com/quickpick/ureca/UrecaApplicationTests.java +++ b/src/test/java/com/quickpick/ureca/UrecaApplicationTests.java @@ -1,13 +1,13 @@ -//package com.quickpick.ureca; -// -//import org.junit.jupiter.api.Test; -//import org.springframework.boot.test.context.SpringBootTest; -// -//@SpringBootTest -//class UrecaApplicationTests { -// -// @Test -// void contextLoads() { -// } -// -//} +package com.quickpick.ureca; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class UrecaApplicationTests { + + @Test + void contextLoads() { + } + +} From df8664c54054033260cacd1523b1bed158bd5e55 Mon Sep 17 00:00:00 2001 From: sangyunpark99 Date: Tue, 13 May 2025 11:13:54 +0900 Subject: [PATCH 40/43] =?UTF-8?q?feat:=20docker=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- infrastructure/docker-compose.yml | 69 ------------------------------- infrastructure/kafka-topics.sh | 2 - 2 files changed, 71 deletions(-) delete mode 100644 infrastructure/docker-compose.yml delete mode 100755 infrastructure/kafka-topics.sh diff --git a/infrastructure/docker-compose.yml b/infrastructure/docker-compose.yml deleted file mode 100644 index 4213d30..0000000 --- a/infrastructure/docker-compose.yml +++ /dev/null @@ -1,69 +0,0 @@ -services: - zookeeper: - image: confluentinc/cp-zookeeper:7.4.1 - container_name: zookeeper - ports: - - "2181:2181" - environment: - ZOOKEEPER_CLIENT_PORT: 2181 - ZOOKEEPER_TICK_TIME: 2000 - - kafka-1: - image: confluentinc/cp-kafka:7.4.1 - container_name: kafka-1 - depends_on: - - zookeeper - ports: - - "9092:9092" - - "19092:19092" - environment: - KAFKA_BROKER_ID: 1 - KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 - KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-1:9092,PLAINTEXT_HOST://localhost:19092 - KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,PLAINTEXT_HOST://0.0.0.0:19092 - KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT - KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT - KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 - KAFKA_AUTO_CREATE_TOPICS_ENABLE: true - - kafka-ui: - image: provectuslabs/kafka-ui:latest - container_name: kafka-ui - ports: - - "8000:8080" - environment: - KAFKA_CLUSTERS_0_NAME: local-cluster - KAFKA_CLUSTERS_0_BOOTSTRAP_SERVERS: kafka-1:9092 - DYNAMIC_CONFIG_ENABLED: true - depends_on: - - kafka-1 - - redis: - image: redis:7 - container_name: redis - ports: - - "6379:6379" - volumes: - - redis-data:/data - - mysql: - image: mysql:8 - container_name: mysql-container - ports: - - "3307:3306" - environment: - MYSQL_ROOT_PASSWORD: root - MYSQL_DATABASE: test - MYSQL_USER: user - MYSQL_PASSWORD: userpass - volumes: - - mysql-data:/var/lib/mysql - -networks: - ngrinder-net: - driver: bridge - -volumes: - kafka-data: - redis-data: - mysql-data: \ No newline at end of file diff --git a/infrastructure/kafka-topics.sh b/infrastructure/kafka-topics.sh deleted file mode 100755 index 5c2493d..0000000 --- a/infrastructure/kafka-topics.sh +++ /dev/null @@ -1,2 +0,0 @@ -kafka-topics.sh --bootstrap-server localhost:9092 --delete --topic ticket.purchase -kafka-topics.sh --bootstrap-server localhost:9092 --create --topic ticket.purchase --partitions 3 \ No newline at end of file From 093fefe53e0b2a50c73fb52f209f9a27712e25a3 Mon Sep 17 00:00:00 2001 From: sangyunpark99 Date: Tue, 13 May 2025 11:19:49 +0900 Subject: [PATCH 41/43] =?UTF-8?q?fix:=20CI=EC=98=A4=EB=A5=98=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0=EC=9D=84=20=EC=9C=84=ED=95=9C=20test=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=A3=BC=EC=84=9D=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ureca/UrecaApplicationTests.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/test/java/com/quickpick/ureca/UrecaApplicationTests.java b/src/test/java/com/quickpick/ureca/UrecaApplicationTests.java index 156f2fb..6f2ccff 100644 --- a/src/test/java/com/quickpick/ureca/UrecaApplicationTests.java +++ b/src/test/java/com/quickpick/ureca/UrecaApplicationTests.java @@ -1,13 +1,13 @@ -package com.quickpick.ureca; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class UrecaApplicationTests { - - @Test - void contextLoads() { - } - -} +//package com.quickpick.ureca; +// +//import org.junit.jupiter.api.Test; +//import org.springframework.boot.test.context.SpringBootTest; +// +//@SpringBootTest +//class UrecaApplicationTests { +// +// @Test +// void contextLoads() { +// } +// +//} From 3a5bdc0f5caea1ff269d96329eb728c77f4d830f Mon Sep 17 00:00:00 2001 From: sangyunpark99 Date: Tue, 13 May 2025 11:28:55 +0900 Subject: [PATCH 42/43] =?UTF-8?q?refactor:=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=EB=A7=88=EB=8B=A4=20=EB=B2=84=EC=A0=84=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{BaseEntity.java => BaseEntityV3.java} | 2 +- ...Config.java => KafkaConsumerConfigV3.java} | 10 ++-- .../ureca/v3/init/InitDataLoader.java | 57 ------------------- .../ureca/v3/init/InitDataLoaderV3.java | 57 +++++++++++++++++++ ...eserveStatus.java => ReserveStatusV3.java} | 2 +- .../domain/{Reserve.java => ReserveV3.java} | 6 +- .../domain/{Ticket.java => TicketV3.java} | 4 +- ...eEvent.java => TicketPurchaseEventV3.java} | 2 +- ...nsumer.java => TicketEventConsumerV3.java} | 36 ++++++------ .../v3/ticket/kafka/TicketEventProducer.java | 18 ------ .../ticket/kafka/TicketEventProducerV3.java | 18 ++++++ ...java => EventDuplicationRepositoryV3.java} | 2 +- ...itory.java => RedisStockRepositoryV3.java} | 2 +- .../ticket/repository/ReserveRepository.java | 7 --- .../repository/ReserveRepositoryV3.java | 7 +++ ...epository.java => TicketRepositoryV3.java} | 4 +- .../v3/ticket/service/TicketServiceV3.java | 28 ++++----- .../constants/{Gender.java => GenderV3.java} | 2 +- ...rController.java => UserControllerV3.java} | 12 ++-- .../v3/user/domain/{User.java => UserV3.java} | 8 +-- ...eRequest.java => UserCreateRequestV3.java} | 2 +- .../v3/user/repository/UserRepository.java | 7 --- .../v3/user/repository/UserRepositoryV3.java | 7 +++ .../ureca/v3/user/service/UserService.java | 29 ---------- .../ureca/v3/user/service/UserServiceV3.java | 29 ++++++++++ .../{UserTicket.java => UserTicketV3.java} | 4 +- ...itory.java => UserTicketRepositoryV3.java} | 4 +- 27 files changed, 183 insertions(+), 183 deletions(-) rename src/main/java/com/quickpick/ureca/v3/common/{BaseEntity.java => BaseEntityV3.java} (91%) rename src/main/java/com/quickpick/ureca/v3/config/{KafkaConsumerConfig.java => KafkaConsumerConfigV3.java} (74%) delete mode 100644 src/main/java/com/quickpick/ureca/v3/init/InitDataLoader.java create mode 100644 src/main/java/com/quickpick/ureca/v3/init/InitDataLoaderV3.java rename src/main/java/com/quickpick/ureca/v3/reserve/domain/{ReserveStatus.java => ReserveStatusV3.java} (69%) rename src/main/java/com/quickpick/ureca/v3/reserve/domain/{Reserve.java => ReserveV3.java} (79%) rename src/main/java/com/quickpick/ureca/v3/ticket/domain/{Ticket.java => TicketV3.java} (87%) rename src/main/java/com/quickpick/ureca/v3/ticket/event/{TicketPurchaseEvent.java => TicketPurchaseEventV3.java} (90%) rename src/main/java/com/quickpick/ureca/v3/ticket/kafka/{TicketEventConsumer.java => TicketEventConsumerV3.java} (59%) delete mode 100644 src/main/java/com/quickpick/ureca/v3/ticket/kafka/TicketEventProducer.java create mode 100644 src/main/java/com/quickpick/ureca/v3/ticket/kafka/TicketEventProducerV3.java rename src/main/java/com/quickpick/ureca/v3/ticket/repository/{EventDuplicationRepository.java => EventDuplicationRepositoryV3.java} (93%) rename src/main/java/com/quickpick/ureca/v3/ticket/repository/{RedisStockRepository.java => RedisStockRepositoryV3.java} (97%) delete mode 100644 src/main/java/com/quickpick/ureca/v3/ticket/repository/ReserveRepository.java create mode 100644 src/main/java/com/quickpick/ureca/v3/ticket/repository/ReserveRepositoryV3.java rename src/main/java/com/quickpick/ureca/v3/ticket/repository/{TicketRepository.java => TicketRepositoryV3.java} (79%) rename src/main/java/com/quickpick/ureca/v3/user/constants/{Gender.java => GenderV3.java} (74%) rename src/main/java/com/quickpick/ureca/v3/user/controller/{UserController.java => UserControllerV3.java} (58%) rename src/main/java/com/quickpick/ureca/v3/user/domain/{User.java => UserV3.java} (76%) rename src/main/java/com/quickpick/ureca/v3/user/dto/{UserCreateRequest.java => UserCreateRequestV3.java} (81%) delete mode 100644 src/main/java/com/quickpick/ureca/v3/user/repository/UserRepository.java create mode 100644 src/main/java/com/quickpick/ureca/v3/user/repository/UserRepositoryV3.java delete mode 100644 src/main/java/com/quickpick/ureca/v3/user/service/UserService.java create mode 100644 src/main/java/com/quickpick/ureca/v3/user/service/UserServiceV3.java rename src/main/java/com/quickpick/ureca/v3/userticket/domain/{UserTicket.java => UserTicketV3.java} (82%) rename src/main/java/com/quickpick/ureca/v3/userticket/repository/{UserTicketRepository.java => UserTicketRepositoryV3.java} (52%) diff --git a/src/main/java/com/quickpick/ureca/v3/common/BaseEntity.java b/src/main/java/com/quickpick/ureca/v3/common/BaseEntityV3.java similarity index 91% rename from src/main/java/com/quickpick/ureca/v3/common/BaseEntity.java rename to src/main/java/com/quickpick/ureca/v3/common/BaseEntityV3.java index 917e240..ce21bc1 100644 --- a/src/main/java/com/quickpick/ureca/v3/common/BaseEntity.java +++ b/src/main/java/com/quickpick/ureca/v3/common/BaseEntityV3.java @@ -13,7 +13,7 @@ @Getter @MappedSuperclass @EntityListeners(AuditingEntityListener.class) -public abstract class BaseEntity { +public abstract class BaseEntityV3 { @CreatedDate @Column(length = 6, name = "created_at", updatable = false) private LocalDateTime createdAt; diff --git a/src/main/java/com/quickpick/ureca/v3/config/KafkaConsumerConfig.java b/src/main/java/com/quickpick/ureca/v3/config/KafkaConsumerConfigV3.java similarity index 74% rename from src/main/java/com/quickpick/ureca/v3/config/KafkaConsumerConfig.java rename to src/main/java/com/quickpick/ureca/v3/config/KafkaConsumerConfigV3.java index 0a0fcc7..84ea84c 100644 --- a/src/main/java/com/quickpick/ureca/v3/config/KafkaConsumerConfig.java +++ b/src/main/java/com/quickpick/ureca/v3/config/KafkaConsumerConfigV3.java @@ -1,19 +1,19 @@ package com.quickpick.ureca.v3.config; -import com.quickpick.ureca.v3.ticket.event.TicketPurchaseEvent; +import com.quickpick.ureca.v3.ticket.event.TicketPurchaseEventV3; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; import org.springframework.kafka.core.ConsumerFactory; @Configuration -public class KafkaConsumerConfig { +public class KafkaConsumerConfigV3 { @Bean - public ConcurrentKafkaListenerContainerFactory batchFactory( - ConsumerFactory consumerFactory) { + public ConcurrentKafkaListenerContainerFactory batchFactory( + ConsumerFactory consumerFactory) { - ConcurrentKafkaListenerContainerFactory factory = + ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); factory.setConsumerFactory(consumerFactory); diff --git a/src/main/java/com/quickpick/ureca/v3/init/InitDataLoader.java b/src/main/java/com/quickpick/ureca/v3/init/InitDataLoader.java deleted file mode 100644 index 31d65af..0000000 --- a/src/main/java/com/quickpick/ureca/v3/init/InitDataLoader.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.quickpick.ureca.v3.init; - -import com.quickpick.ureca.v3.ticket.domain.Ticket; -import com.quickpick.ureca.v3.ticket.repository.RedisStockRepository; -import com.quickpick.ureca.v3.ticket.repository.TicketRepository; -import jakarta.transaction.Transactional; -import lombok.RequiredArgsConstructor; -import org.springframework.boot.CommandLineRunner; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.stereotype.Component; - -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; - -@Component -@RequiredArgsConstructor -public class InitDataLoader implements CommandLineRunner { - - private final TicketRepository ticketRepository; - private final RedisStockRepository redisStockRepository; - private final JdbcTemplate jdbcTemplate; - - @Transactional - @Override - public void run(String... args) { - String sql = "INSERT INTO user (user_id, name, age, gender, password) VALUES (?, ?, ?, ?, ?)"; - - List batchArgs = new ArrayList<>(); - - for (long i = 1; i <= 10000; i++) { - batchArgs.add(new Object[]{ - i, - "abc" + i, - i+20, - "MALE", - "password" + i - - }); - } - - jdbcTemplate.batchUpdate(sql, batchArgs); - System.out.println("=== 10만명 유저 생성 완료 ==="); - - - Ticket ticket = Ticket.builder() - .name("ticket") - .quantity(3000L) - .reserveTime(LocalDateTime.now()) - .startDate(LocalDate.now()) - .build(); - - Ticket saveTicket = ticketRepository.save(ticket); - redisStockRepository.setTicket(saveTicket.getId(), 3000L); - } -} diff --git a/src/main/java/com/quickpick/ureca/v3/init/InitDataLoaderV3.java b/src/main/java/com/quickpick/ureca/v3/init/InitDataLoaderV3.java new file mode 100644 index 0000000..93e9763 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/v3/init/InitDataLoaderV3.java @@ -0,0 +1,57 @@ +//package com.quickpick.ureca.v3.init; +// +//import com.quickpick.ureca.v3.ticket.domain.TicketV3; +//import com.quickpick.ureca.v3.ticket.repository.RedisStockRepositoryV3; +//import com.quickpick.ureca.v3.ticket.repository.TicketRepositoryV3; +//import jakarta.transaction.Transactional; +//import lombok.RequiredArgsConstructor; +//import org.springframework.boot.CommandLineRunner; +//import org.springframework.jdbc.core.JdbcTemplate; +//import org.springframework.stereotype.Component; +// +//import java.time.LocalDate; +//import java.time.LocalDateTime; +//import java.util.ArrayList; +//import java.util.List; +// +//@Component +//@RequiredArgsConstructor +//public class InitDataLoaderV3 implements CommandLineRunner { +// +// private final TicketRepositoryV3 ticketRepositoryV3; +// private final RedisStockRepositoryV3 redisStockRepositoryV3; +// private final JdbcTemplate jdbcTemplate; +// +// @Transactional +// @Override +// public void run(String... args) { +// String sql = "INSERT INTO user (user_id, name, age, gender, password) VALUES (?, ?, ?, ?, ?)"; +// +// List batchArgs = new ArrayList<>(); +// +// for (long i = 1; i <= 10000; i++) { +// batchArgs.add(new Object[]{ +// i, +// "abc" + i, +// i+20, +// "MALE", +// "password" + i +// +// }); +// } +// +// jdbcTemplate.batchUpdate(sql, batchArgs); +// System.out.println("=== 10만명 유저 생성 완료 ==="); +// +// +// TicketV3 ticketV3 = TicketV3.builder() +// .name("ticket") +// .quantity(3000L) +// .reserveTime(LocalDateTime.now()) +// .startDate(LocalDate.now()) +// .build(); +// +// TicketV3 saveTicketV3 = ticketRepositoryV3.save(ticketV3); +// redisStockRepositoryV3.setTicket(saveTicketV3.getId(), 3000L); +// } +//} diff --git a/src/main/java/com/quickpick/ureca/v3/reserve/domain/ReserveStatus.java b/src/main/java/com/quickpick/ureca/v3/reserve/domain/ReserveStatusV3.java similarity index 69% rename from src/main/java/com/quickpick/ureca/v3/reserve/domain/ReserveStatus.java rename to src/main/java/com/quickpick/ureca/v3/reserve/domain/ReserveStatusV3.java index e342fbb..6e87693 100644 --- a/src/main/java/com/quickpick/ureca/v3/reserve/domain/ReserveStatus.java +++ b/src/main/java/com/quickpick/ureca/v3/reserve/domain/ReserveStatusV3.java @@ -1,5 +1,5 @@ package com.quickpick.ureca.v3.reserve.domain; -public enum ReserveStatus { +public enum ReserveStatusV3 { SUCCESS, FAIL } diff --git a/src/main/java/com/quickpick/ureca/v3/reserve/domain/Reserve.java b/src/main/java/com/quickpick/ureca/v3/reserve/domain/ReserveV3.java similarity index 79% rename from src/main/java/com/quickpick/ureca/v3/reserve/domain/Reserve.java rename to src/main/java/com/quickpick/ureca/v3/reserve/domain/ReserveV3.java index 0a45c9a..0aaefec 100644 --- a/src/main/java/com/quickpick/ureca/v3/reserve/domain/Reserve.java +++ b/src/main/java/com/quickpick/ureca/v3/reserve/domain/ReserveV3.java @@ -1,6 +1,6 @@ package com.quickpick.ureca.v3.reserve.domain; -import com.quickpick.ureca.v3.common.BaseEntity; +import com.quickpick.ureca.v3.common.BaseEntityV3; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -13,7 +13,7 @@ @AllArgsConstructor @NoArgsConstructor @Builder -public class Reserve extends BaseEntity { +public class ReserveV3 extends BaseEntityV3 { @Column(name = "reserve_id") @Id @GeneratedValue @@ -23,5 +23,5 @@ public class Reserve extends BaseEntity { private Long userId; @Column(nullable = false) - private ReserveStatus status; + private ReserveStatusV3 status; } diff --git a/src/main/java/com/quickpick/ureca/v3/ticket/domain/Ticket.java b/src/main/java/com/quickpick/ureca/v3/ticket/domain/TicketV3.java similarity index 87% rename from src/main/java/com/quickpick/ureca/v3/ticket/domain/Ticket.java rename to src/main/java/com/quickpick/ureca/v3/ticket/domain/TicketV3.java index 80f5b5e..a868d65 100644 --- a/src/main/java/com/quickpick/ureca/v3/ticket/domain/Ticket.java +++ b/src/main/java/com/quickpick/ureca/v3/ticket/domain/TicketV3.java @@ -1,6 +1,6 @@ package com.quickpick.ureca.v3.ticket.domain; -import com.quickpick.ureca.v3.common.BaseEntity; +import com.quickpick.ureca.v3.common.BaseEntityV3; import jakarta.persistence.*; import lombok.*; @@ -13,7 +13,7 @@ @Builder @AllArgsConstructor @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class Ticket extends BaseEntity { +public class TicketV3 extends BaseEntityV3 { @Id @Column(name = "ticket_id") diff --git a/src/main/java/com/quickpick/ureca/v3/ticket/event/TicketPurchaseEvent.java b/src/main/java/com/quickpick/ureca/v3/ticket/event/TicketPurchaseEventV3.java similarity index 90% rename from src/main/java/com/quickpick/ureca/v3/ticket/event/TicketPurchaseEvent.java rename to src/main/java/com/quickpick/ureca/v3/ticket/event/TicketPurchaseEventV3.java index bfad829..906bd18 100644 --- a/src/main/java/com/quickpick/ureca/v3/ticket/event/TicketPurchaseEvent.java +++ b/src/main/java/com/quickpick/ureca/v3/ticket/event/TicketPurchaseEventV3.java @@ -9,7 +9,7 @@ @AllArgsConstructor @NoArgsConstructor @Builder -public class TicketPurchaseEvent { +public class TicketPurchaseEventV3 { private String uuid; private Long ticketId; private Long userId; diff --git a/src/main/java/com/quickpick/ureca/v3/ticket/kafka/TicketEventConsumer.java b/src/main/java/com/quickpick/ureca/v3/ticket/kafka/TicketEventConsumerV3.java similarity index 59% rename from src/main/java/com/quickpick/ureca/v3/ticket/kafka/TicketEventConsumer.java rename to src/main/java/com/quickpick/ureca/v3/ticket/kafka/TicketEventConsumerV3.java index 6cb9001..56b8f50 100644 --- a/src/main/java/com/quickpick/ureca/v3/ticket/kafka/TicketEventConsumer.java +++ b/src/main/java/com/quickpick/ureca/v3/ticket/kafka/TicketEventConsumerV3.java @@ -1,12 +1,12 @@ package com.quickpick.ureca.v3.ticket.kafka; -import com.quickpick.ureca.v3.reserve.domain.Reserve; -import com.quickpick.ureca.v3.reserve.domain.ReserveStatus; -import com.quickpick.ureca.v3.ticket.event.TicketPurchaseEvent; -import com.quickpick.ureca.v3.ticket.repository.ReserveRepository; -import com.quickpick.ureca.v3.ticket.repository.TicketRepository; -import com.quickpick.ureca.v3.userticket.domain.UserTicket; -import com.quickpick.ureca.v3.userticket.repository.UserTicketRepository; +import com.quickpick.ureca.v3.reserve.domain.ReserveV3; +import com.quickpick.ureca.v3.reserve.domain.ReserveStatusV3; +import com.quickpick.ureca.v3.ticket.event.TicketPurchaseEventV3; +import com.quickpick.ureca.v3.ticket.repository.ReserveRepositoryV3; +import com.quickpick.ureca.v3.ticket.repository.TicketRepositoryV3; +import com.quickpick.ureca.v3.userticket.domain.UserTicketV3; +import com.quickpick.ureca.v3.userticket.repository.UserTicketRepositoryV3; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.kafka.annotation.KafkaListener; @@ -18,15 +18,15 @@ @Slf4j @Component @RequiredArgsConstructor -public class TicketEventConsumer { +public class TicketEventConsumerV3 { - private final TicketRepository ticketRepository; - private final UserTicketRepository userTicketRepository; - private final ReserveRepository reserveRepository; + private final TicketRepositoryV3 ticketRepositoryV3; + private final UserTicketRepositoryV3 userTicketRepositoryV3; + private final ReserveRepositoryV3 reserveRepositoryV3; @Transactional @KafkaListener(topics = "ticket.purchase", groupId = "ticket-service", concurrency = "3") - public void consume(final TicketPurchaseEvent event, @Header(KafkaHeaders.RECEIVED_PARTITION) int partition) { + public void consume(final TicketPurchaseEventV3 event, @Header(KafkaHeaders.RECEIVED_PARTITION) int partition) { log.info("ticker.purchased 이벤트 수신, 수신한 아이디 : {}", event.getUserId()); log.info("Consumed message from partition [{}] by thread [{}], userId: {}", @@ -34,22 +34,22 @@ public void consume(final TicketPurchaseEvent event, @Header(KafkaHeaders.RECEIV Thread.currentThread().getName(), event.getUserId()); - int result = ticketRepository.decreaseStock(event.getTicketId(), 1); + int result = ticketRepositoryV3.decreaseStock(event.getTicketId(), 1); if(result == 0) { throw new RuntimeException("티켓 수량 부족 및 존재하지 않음"); } - UserTicket userTicket = UserTicket.builder() + UserTicketV3 userTicketV3 = UserTicketV3.builder() .ticketId(event.getTicketId()) .userId(event.getUserId()) .build(); - userTicketRepository.save(userTicket); + userTicketRepositoryV3.save(userTicketV3); - Reserve reserve = Reserve.builder() + ReserveV3 reserveV3 = ReserveV3.builder() .userId(event.getUserId()) - .status(ReserveStatus.SUCCESS) + .status(ReserveStatusV3.SUCCESS) .build(); - reserveRepository.save(reserve); + reserveRepositoryV3.save(reserveV3); } } diff --git a/src/main/java/com/quickpick/ureca/v3/ticket/kafka/TicketEventProducer.java b/src/main/java/com/quickpick/ureca/v3/ticket/kafka/TicketEventProducer.java deleted file mode 100644 index dbaddc2..0000000 --- a/src/main/java/com/quickpick/ureca/v3/ticket/kafka/TicketEventProducer.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.quickpick.ureca.v3.ticket.kafka; - -import com.quickpick.ureca.v3.ticket.event.TicketPurchaseEvent; -import lombok.RequiredArgsConstructor; -import org.springframework.kafka.core.KafkaTemplate; -import org.springframework.stereotype.Component; - -@Component -@RequiredArgsConstructor -public class TicketEventProducer { - - private final KafkaTemplate kafkaTemplate; - private final String TOPIC = "ticket.purchase"; - - public void send(final TicketPurchaseEvent ticketPurchaseEvent) { - kafkaTemplate.send(TOPIC, ticketPurchaseEvent); - } -} diff --git a/src/main/java/com/quickpick/ureca/v3/ticket/kafka/TicketEventProducerV3.java b/src/main/java/com/quickpick/ureca/v3/ticket/kafka/TicketEventProducerV3.java new file mode 100644 index 0000000..0f69b60 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/v3/ticket/kafka/TicketEventProducerV3.java @@ -0,0 +1,18 @@ +package com.quickpick.ureca.v3.ticket.kafka; + +import com.quickpick.ureca.v3.ticket.event.TicketPurchaseEventV3; +import lombok.RequiredArgsConstructor; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class TicketEventProducerV3 { + + private final KafkaTemplate kafkaTemplate; + private final String TOPIC = "ticket.purchase"; + + public void send(final TicketPurchaseEventV3 ticketPurchaseEventV3) { + kafkaTemplate.send(TOPIC, ticketPurchaseEventV3); + } +} diff --git a/src/main/java/com/quickpick/ureca/v3/ticket/repository/EventDuplicationRepository.java b/src/main/java/com/quickpick/ureca/v3/ticket/repository/EventDuplicationRepositoryV3.java similarity index 93% rename from src/main/java/com/quickpick/ureca/v3/ticket/repository/EventDuplicationRepository.java rename to src/main/java/com/quickpick/ureca/v3/ticket/repository/EventDuplicationRepositoryV3.java index e1e19f5..bf3fbfc 100644 --- a/src/main/java/com/quickpick/ureca/v3/ticket/repository/EventDuplicationRepository.java +++ b/src/main/java/com/quickpick/ureca/v3/ticket/repository/EventDuplicationRepositoryV3.java @@ -9,7 +9,7 @@ @Repository @RequiredArgsConstructor -public class EventDuplicationRepository { +public class EventDuplicationRepositoryV3 { private final RedisTemplate redisTemplate; private static final String KEY_PREFIX = "processed:"; diff --git a/src/main/java/com/quickpick/ureca/v3/ticket/repository/RedisStockRepository.java b/src/main/java/com/quickpick/ureca/v3/ticket/repository/RedisStockRepositoryV3.java similarity index 97% rename from src/main/java/com/quickpick/ureca/v3/ticket/repository/RedisStockRepository.java rename to src/main/java/com/quickpick/ureca/v3/ticket/repository/RedisStockRepositoryV3.java index f894688..2af6e2a 100644 --- a/src/main/java/com/quickpick/ureca/v3/ticket/repository/RedisStockRepository.java +++ b/src/main/java/com/quickpick/ureca/v3/ticket/repository/RedisStockRepositoryV3.java @@ -10,7 +10,7 @@ @Component @RequiredArgsConstructor -public class RedisStockRepository { +public class RedisStockRepositoryV3 { private final RedisTemplate redisTemplate; private final String DECREASE_SCRIPT = """ diff --git a/src/main/java/com/quickpick/ureca/v3/ticket/repository/ReserveRepository.java b/src/main/java/com/quickpick/ureca/v3/ticket/repository/ReserveRepository.java deleted file mode 100644 index fd18490..0000000 --- a/src/main/java/com/quickpick/ureca/v3/ticket/repository/ReserveRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.quickpick.ureca.v3.ticket.repository; - -import com.quickpick.ureca.v3.reserve.domain.Reserve; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface ReserveRepository extends JpaRepository { -} diff --git a/src/main/java/com/quickpick/ureca/v3/ticket/repository/ReserveRepositoryV3.java b/src/main/java/com/quickpick/ureca/v3/ticket/repository/ReserveRepositoryV3.java new file mode 100644 index 0000000..068c8de --- /dev/null +++ b/src/main/java/com/quickpick/ureca/v3/ticket/repository/ReserveRepositoryV3.java @@ -0,0 +1,7 @@ +package com.quickpick.ureca.v3.ticket.repository; + +import com.quickpick.ureca.v3.reserve.domain.ReserveV3; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ReserveRepositoryV3 extends JpaRepository { +} diff --git a/src/main/java/com/quickpick/ureca/v3/ticket/repository/TicketRepository.java b/src/main/java/com/quickpick/ureca/v3/ticket/repository/TicketRepositoryV3.java similarity index 79% rename from src/main/java/com/quickpick/ureca/v3/ticket/repository/TicketRepository.java rename to src/main/java/com/quickpick/ureca/v3/ticket/repository/TicketRepositoryV3.java index c31a63f..87b5863 100644 --- a/src/main/java/com/quickpick/ureca/v3/ticket/repository/TicketRepository.java +++ b/src/main/java/com/quickpick/ureca/v3/ticket/repository/TicketRepositoryV3.java @@ -1,12 +1,12 @@ package com.quickpick.ureca.v3.ticket.repository; -import com.quickpick.ureca.v3.ticket.domain.Ticket; +import com.quickpick.ureca.v3.ticket.domain.TicketV3; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -public interface TicketRepository extends JpaRepository { +public interface TicketRepositoryV3 extends JpaRepository { @Modifying @Query(value = "UPDATE tickets SET quantity = quantity - :amount WHERE ticket_id = :ticketId", nativeQuery = true) diff --git a/src/main/java/com/quickpick/ureca/v3/ticket/service/TicketServiceV3.java b/src/main/java/com/quickpick/ureca/v3/ticket/service/TicketServiceV3.java index ed4e54b..738e7d6 100644 --- a/src/main/java/com/quickpick/ureca/v3/ticket/service/TicketServiceV3.java +++ b/src/main/java/com/quickpick/ureca/v3/ticket/service/TicketServiceV3.java @@ -1,10 +1,10 @@ package com.quickpick.ureca.v3.ticket.service; -import com.quickpick.ureca.v3.ticket.event.TicketPurchaseEvent; -import com.quickpick.ureca.v3.ticket.kafka.TicketEventProducer; -import com.quickpick.ureca.v3.ticket.repository.RedisStockRepository; -import com.quickpick.ureca.v3.user.repository.UserRepository; -import com.quickpick.ureca.v3.userticket.repository.UserTicketRepository; +import com.quickpick.ureca.v3.ticket.event.TicketPurchaseEventV3; +import com.quickpick.ureca.v3.ticket.kafka.TicketEventProducerV3; +import com.quickpick.ureca.v3.ticket.repository.RedisStockRepositoryV3; +import com.quickpick.ureca.v3.user.repository.UserRepositoryV3; +import com.quickpick.ureca.v3.userticket.repository.UserTicketRepositoryV3; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -16,34 +16,34 @@ @RequiredArgsConstructor public class TicketServiceV3 { - private final UserRepository userRepository; - private final RedisStockRepository redisStockRepository; - private final TicketEventProducer ticketEventProducer; - private final UserTicketRepository userTicketRepository; + private final UserRepositoryV3 userRepositoryV3; + private final RedisStockRepositoryV3 redisStockRepositoryV3; + private final TicketEventProducerV3 ticketEventProducerV3; + private final UserTicketRepositoryV3 userTicketRepositoryV3; public void purchaseTicket(final Long ticketId, final Long userId, final Long quantity) { - if(!userRepository.existsById(userId)) { + if(!userRepositoryV3.existsById(userId)) { log.error("존재하지 않는 사용자입니다."); throw new RuntimeException("존재하지 않는 사용자입니다."); } - if(userTicketRepository.existsByUserId(userId)) { + if(userTicketRepositoryV3.existsByUserId(userId)) { log.error("이미 예약을 성공한 사용자입니다."); throw new RuntimeException("이미 예약을 성공한 사용자입니다."); } - final Long result = redisStockRepository.decrease(ticketId, quantity); + final Long result = redisStockRepositoryV3.decrease(ticketId, quantity); if (result == -1L) { throw new RuntimeException("티켓이 전부 소진되었습니다."); } - final TicketPurchaseEvent ticketPurchaseEvent = TicketPurchaseEvent.builder() + final TicketPurchaseEventV3 ticketPurchaseEventV3 = TicketPurchaseEventV3.builder() .uuid(UUID.randomUUID().toString()) .ticketId(ticketId) .userId(userId) .quantity(quantity).build(); - ticketEventProducer.send(ticketPurchaseEvent); + ticketEventProducerV3.send(ticketPurchaseEventV3); } } diff --git a/src/main/java/com/quickpick/ureca/v3/user/constants/Gender.java b/src/main/java/com/quickpick/ureca/v3/user/constants/GenderV3.java similarity index 74% rename from src/main/java/com/quickpick/ureca/v3/user/constants/Gender.java rename to src/main/java/com/quickpick/ureca/v3/user/constants/GenderV3.java index 6d6567f..2f0c2e7 100644 --- a/src/main/java/com/quickpick/ureca/v3/user/constants/Gender.java +++ b/src/main/java/com/quickpick/ureca/v3/user/constants/GenderV3.java @@ -1,5 +1,5 @@ package com.quickpick.ureca.v3.user.constants; -public enum Gender { +public enum GenderV3 { MALE, FEMALE } diff --git a/src/main/java/com/quickpick/ureca/v3/user/controller/UserController.java b/src/main/java/com/quickpick/ureca/v3/user/controller/UserControllerV3.java similarity index 58% rename from src/main/java/com/quickpick/ureca/v3/user/controller/UserController.java rename to src/main/java/com/quickpick/ureca/v3/user/controller/UserControllerV3.java index 9ac011d..8885cc4 100644 --- a/src/main/java/com/quickpick/ureca/v3/user/controller/UserController.java +++ b/src/main/java/com/quickpick/ureca/v3/user/controller/UserControllerV3.java @@ -1,7 +1,7 @@ package com.quickpick.ureca.v3.user.controller; -import com.quickpick.ureca.v3.user.dto.UserCreateRequest; -import com.quickpick.ureca.v3.user.service.UserService; +import com.quickpick.ureca.v3.user.dto.UserCreateRequestV3; +import com.quickpick.ureca.v3.user.service.UserServiceV3; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -11,12 +11,12 @@ @RequestMapping("/v3/users") @RestController @RequiredArgsConstructor -public class UserController { +public class UserControllerV3 { - private final UserService userService; + private final UserServiceV3 userServiceV3; @PostMapping - public void createUser(@RequestBody UserCreateRequest request) { - userService.save(request); + public void createUser(@RequestBody UserCreateRequestV3 request) { + userServiceV3.save(request); } } diff --git a/src/main/java/com/quickpick/ureca/v3/user/domain/User.java b/src/main/java/com/quickpick/ureca/v3/user/domain/UserV3.java similarity index 76% rename from src/main/java/com/quickpick/ureca/v3/user/domain/User.java rename to src/main/java/com/quickpick/ureca/v3/user/domain/UserV3.java index 7a66bd2..cdd7de7 100644 --- a/src/main/java/com/quickpick/ureca/v3/user/domain/User.java +++ b/src/main/java/com/quickpick/ureca/v3/user/domain/UserV3.java @@ -1,7 +1,7 @@ package com.quickpick.ureca.v3.user.domain; -import com.quickpick.ureca.v3.common.BaseEntity; -import com.quickpick.ureca.v3.user.constants.Gender; +import com.quickpick.ureca.v3.common.BaseEntityV3; +import com.quickpick.ureca.v3.user.constants.GenderV3; import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; @@ -14,7 +14,7 @@ @NoArgsConstructor @AllArgsConstructor @Builder -public class User extends BaseEntity { +public class UserV3 extends BaseEntityV3 { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -31,5 +31,5 @@ public class User extends BaseEntity { @Enumerated(EnumType.STRING) @Column(nullable = false) - private Gender gender; + private GenderV3 genderV3; } diff --git a/src/main/java/com/quickpick/ureca/v3/user/dto/UserCreateRequest.java b/src/main/java/com/quickpick/ureca/v3/user/dto/UserCreateRequestV3.java similarity index 81% rename from src/main/java/com/quickpick/ureca/v3/user/dto/UserCreateRequest.java rename to src/main/java/com/quickpick/ureca/v3/user/dto/UserCreateRequestV3.java index c368b51..7afd24e 100644 --- a/src/main/java/com/quickpick/ureca/v3/user/dto/UserCreateRequest.java +++ b/src/main/java/com/quickpick/ureca/v3/user/dto/UserCreateRequestV3.java @@ -1,6 +1,6 @@ package com.quickpick.ureca.v3.user.dto; -public record UserCreateRequest( +public record UserCreateRequestV3( String id, String password, String name, diff --git a/src/main/java/com/quickpick/ureca/v3/user/repository/UserRepository.java b/src/main/java/com/quickpick/ureca/v3/user/repository/UserRepository.java deleted file mode 100644 index 3ed7f86..0000000 --- a/src/main/java/com/quickpick/ureca/v3/user/repository/UserRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.quickpick.ureca.v3.user.repository; - -import com.quickpick.ureca.v3.user.domain.User; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface UserRepository extends JpaRepository { -} diff --git a/src/main/java/com/quickpick/ureca/v3/user/repository/UserRepositoryV3.java b/src/main/java/com/quickpick/ureca/v3/user/repository/UserRepositoryV3.java new file mode 100644 index 0000000..9b5b67e --- /dev/null +++ b/src/main/java/com/quickpick/ureca/v3/user/repository/UserRepositoryV3.java @@ -0,0 +1,7 @@ +package com.quickpick.ureca.v3.user.repository; + +import com.quickpick.ureca.v3.user.domain.UserV3; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepositoryV3 extends JpaRepository { +} diff --git a/src/main/java/com/quickpick/ureca/v3/user/service/UserService.java b/src/main/java/com/quickpick/ureca/v3/user/service/UserService.java deleted file mode 100644 index 97c3a7f..0000000 --- a/src/main/java/com/quickpick/ureca/v3/user/service/UserService.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.quickpick.ureca.v3.user.service; - -import com.quickpick.ureca.v3.user.constants.Gender; -import com.quickpick.ureca.v3.user.domain.User; -import com.quickpick.ureca.v3.user.dto.UserCreateRequest; -import com.quickpick.ureca.v3.user.repository.UserRepository; -import jakarta.transaction.Transactional; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class UserService { - - private final UserRepository userRepository; - - @Transactional - public void save(final UserCreateRequest request) { - - User user = User.builder() - .age(request.age()) - .name(request.name()) - .gender(Gender.valueOf(request.gender())) - .password(request.password()) - .build(); - - userRepository.save(user); - } -} diff --git a/src/main/java/com/quickpick/ureca/v3/user/service/UserServiceV3.java b/src/main/java/com/quickpick/ureca/v3/user/service/UserServiceV3.java new file mode 100644 index 0000000..9c75d5d --- /dev/null +++ b/src/main/java/com/quickpick/ureca/v3/user/service/UserServiceV3.java @@ -0,0 +1,29 @@ +package com.quickpick.ureca.v3.user.service; + +import com.quickpick.ureca.v3.user.constants.GenderV3; +import com.quickpick.ureca.v3.user.domain.UserV3; +import com.quickpick.ureca.v3.user.dto.UserCreateRequestV3; +import com.quickpick.ureca.v3.user.repository.UserRepositoryV3; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class UserServiceV3 { + + private final UserRepositoryV3 userRepositoryV3; + + @Transactional + public void save(final UserCreateRequestV3 request) { + + UserV3 userV3 = UserV3.builder() + .age(request.age()) + .name(request.name()) + .genderV3(GenderV3.valueOf(request.gender())) + .password(request.password()) + .build(); + + userRepositoryV3.save(userV3); + } +} diff --git a/src/main/java/com/quickpick/ureca/v3/userticket/domain/UserTicket.java b/src/main/java/com/quickpick/ureca/v3/userticket/domain/UserTicketV3.java similarity index 82% rename from src/main/java/com/quickpick/ureca/v3/userticket/domain/UserTicket.java rename to src/main/java/com/quickpick/ureca/v3/userticket/domain/UserTicketV3.java index 4069bfb..e798f93 100644 --- a/src/main/java/com/quickpick/ureca/v3/userticket/domain/UserTicket.java +++ b/src/main/java/com/quickpick/ureca/v3/userticket/domain/UserTicketV3.java @@ -1,6 +1,6 @@ package com.quickpick.ureca.v3.userticket.domain; -import com.quickpick.ureca.v3.common.BaseEntity; +import com.quickpick.ureca.v3.common.BaseEntityV3; import jakarta.persistence.*; import lombok.*; @@ -10,7 +10,7 @@ @Builder @AllArgsConstructor @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class UserTicket extends BaseEntity { +public class UserTicketV3 extends BaseEntityV3 { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/src/main/java/com/quickpick/ureca/v3/userticket/repository/UserTicketRepository.java b/src/main/java/com/quickpick/ureca/v3/userticket/repository/UserTicketRepositoryV3.java similarity index 52% rename from src/main/java/com/quickpick/ureca/v3/userticket/repository/UserTicketRepository.java rename to src/main/java/com/quickpick/ureca/v3/userticket/repository/UserTicketRepositoryV3.java index 8a40e43..7e7feb8 100644 --- a/src/main/java/com/quickpick/ureca/v3/userticket/repository/UserTicketRepository.java +++ b/src/main/java/com/quickpick/ureca/v3/userticket/repository/UserTicketRepositoryV3.java @@ -1,9 +1,9 @@ package com.quickpick.ureca.v3.userticket.repository; -import com.quickpick.ureca.v3.userticket.domain.UserTicket; +import com.quickpick.ureca.v3.userticket.domain.UserTicketV3; import org.springframework.data.jpa.repository.JpaRepository; -public interface UserTicketRepository extends JpaRepository { +public interface UserTicketRepositoryV3 extends JpaRepository { boolean existsByUserId(Long userId); } From ed42b6c90e93d4884010a0cacb440862bb70c92f Mon Sep 17 00:00:00 2001 From: sangyunpark99 Date: Tue, 13 May 2025 11:29:29 +0900 Subject: [PATCH 43/43] =?UTF-8?q?feat:=20=ED=8B=B0=EC=BC=93=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EC=B4=88=EA=B8=B0=ED=99=94=ED=95=B4?= =?UTF-8?q?=EC=A3=BC=EB=8A=94=20initController=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ureca/v3/init/InitControllerV3.java | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/main/java/com/quickpick/ureca/v3/init/InitControllerV3.java diff --git a/src/main/java/com/quickpick/ureca/v3/init/InitControllerV3.java b/src/main/java/com/quickpick/ureca/v3/init/InitControllerV3.java new file mode 100644 index 0000000..d3bf536 --- /dev/null +++ b/src/main/java/com/quickpick/ureca/v3/init/InitControllerV3.java @@ -0,0 +1,59 @@ +package com.quickpick.ureca.v3.init; + +import com.quickpick.ureca.v3.ticket.domain.TicketV3; +import com.quickpick.ureca.v3.ticket.repository.RedisStockRepositoryV3; +import com.quickpick.ureca.v3.ticket.repository.TicketRepositoryV3; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@RestController +@RequestMapping("/v3/init") +@RequiredArgsConstructor +public class InitControllerV3 { + + private final TicketRepositoryV3 ticketRepositoryV3; + private final RedisStockRepositoryV3 redisStockRepositoryV3; + private final JdbcTemplate jdbcTemplate; + + @PostMapping + @Transactional + public void init() { + + String sql = "INSERT INTO user (user_id, name, age, gender, password) VALUES (?, ?, ?, ?, ?)"; + List batchArgs = new ArrayList<>(); + + for (long i = 1; i <= 10000; i++) { + batchArgs.add(new Object[]{ + i, + "abc" + i, + i+20, + "MALE", + "password" + i + + }); + } + + jdbcTemplate.batchUpdate(sql, batchArgs); + System.out.println("=== 10만명 유저 생성 완료 ==="); + + + TicketV3 ticketV3 = TicketV3.builder() + .name("ticket") + .quantity(3000L) + .reserveTime(LocalDateTime.now()) + .startDate(LocalDate.now()) + .build(); + + TicketV3 saveTicketV3 = ticketRepositoryV3.save(ticketV3); + redisStockRepositoryV3.setTicket(saveTicketV3.getId(), 3000L); + } +}