From 1fb16e6a352470e9523936b9ccf08a990918d7b1 Mon Sep 17 00:00:00 2001 From: "aj4941@naver.com" Date: Thu, 18 Jul 2024 18:07:10 +0900 Subject: [PATCH 1/7] =?UTF-8?q?:pencil2:=20=EB=AC=B8=EC=A0=9C=20=ED=8B=B0?= =?UTF-8?q?=EC=96=B4=20=EB=B2=94=EC=9C=84=EC=99=80=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=EB=90=9C=20=EC=98=88=EC=99=B8=EB=A5=BC=20=EC=BB=A4=EC=8A=A4?= =?UTF-8?q?=ED=85=80=20=EC=98=88=EC=99=B8=20=EC=BD=94=EB=93=9C=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/model/defense/ProblemTier.java | 4 +++- .../domain/model/error/ProblemErrorCode.java | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/main/java/kr/co/morandi/backend/problem_information/domain/model/error/ProblemErrorCode.java diff --git a/src/main/java/kr/co/morandi/backend/defense_information/domain/model/defense/ProblemTier.java b/src/main/java/kr/co/morandi/backend/defense_information/domain/model/defense/ProblemTier.java index 44d5db17..83213095 100644 --- a/src/main/java/kr/co/morandi/backend/defense_information/domain/model/defense/ProblemTier.java +++ b/src/main/java/kr/co/morandi/backend/defense_information/domain/model/defense/ProblemTier.java @@ -1,5 +1,7 @@ package kr.co.morandi.backend.defense_information.domain.model.defense; +import kr.co.morandi.backend.common.exception.MorandiException; +import kr.co.morandi.backend.problem_information.domain.model.error.ProblemErrorCode; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -23,7 +25,7 @@ public enum ProblemTier { public static List tierRangeOf(ProblemTier start, ProblemTier end) { if (start.tier > end.tier) - throw new IllegalArgumentException("시작 티어가 끝 티어보다 높을 수 없습니다."); + throw new MorandiException(ProblemErrorCode.PROBLEM_TIER_ERROR); return VALUES.stream() .filter(tier -> tier.tier >= start.tier && tier.tier <= end.tier) diff --git a/src/main/java/kr/co/morandi/backend/problem_information/domain/model/error/ProblemErrorCode.java b/src/main/java/kr/co/morandi/backend/problem_information/domain/model/error/ProblemErrorCode.java new file mode 100644 index 00000000..5da778a0 --- /dev/null +++ b/src/main/java/kr/co/morandi/backend/problem_information/domain/model/error/ProblemErrorCode.java @@ -0,0 +1,23 @@ +package kr.co.morandi.backend.problem_information.domain.model.error; + +import kr.co.morandi.backend.common.exception.errorcode.ErrorCode; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; + +@RequiredArgsConstructor +public enum ProblemErrorCode implements ErrorCode { + PROBLEM_TIER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "시작 티어가 끝 티어보다 높을 수 없습니다."); + + private final HttpStatus httpStatus; + private final String message; + + @Override + public HttpStatus getHttpStatus() { + return httpStatus; + } + + @Override + public String getMessage() { + return message; + } +} From c2671eec1515df0567389e3a8677421d3969566b Mon Sep 17 00:00:00 2001 From: "aj4941@naver.com" Date: Tue, 20 Aug 2024 14:53:52 +0900 Subject: [PATCH 2/7] =?UTF-8?q?:pencil2:=20=EC=98=A4=EB=8A=98=EC=9D=98=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=EC=BF=BC=EB=A6=AC=20=EC=B5=9C=EC=A0=81?= =?UTF-8?q?=ED=99=94=20(=EC=9D=B8=EB=8D=B1=EC=8B=B1,=20Left=20Join,=20?= =?UTF-8?q?=EC=95=A0=ED=94=8C=EB=A6=AC=EC=BC=80=EC=9D=B4=EC=85=98=20Random?= =?UTF-8?q?=20=EC=A0=81=EC=9A=A9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dailydefense/DailyDefenseProblemAdapter.java | 14 ++++++++------ .../domain/model/problem/Problem.java | 3 +++ .../persistence/problem/ProblemRepository.java | 11 +++++------ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/main/java/kr/co/morandi/backend/defense_information/infrastructure/adapter/dailydefense/DailyDefenseProblemAdapter.java b/src/main/java/kr/co/morandi/backend/defense_information/infrastructure/adapter/dailydefense/DailyDefenseProblemAdapter.java index 1e18aef5..a6b2f760 100644 --- a/src/main/java/kr/co/morandi/backend/defense_information/infrastructure/adapter/dailydefense/DailyDefenseProblemAdapter.java +++ b/src/main/java/kr/co/morandi/backend/defense_information/infrastructure/adapter/dailydefense/DailyDefenseProblemAdapter.java @@ -14,6 +14,7 @@ import java.util.List; import java.util.Map; +import java.util.Random; import java.util.stream.Collectors; @Component @@ -27,7 +28,8 @@ public class DailyDefenseProblemAdapter implements DailyDefenseProblemPort { @Override public Map getDailyDefenseProblem(Map criteria) { - Pageable pageable = PageRequest.of(0, 1); + Pageable pageable = PageRequest.of(0, 50); + Random random = new Random(); return criteria.entrySet().stream() .map(entry -> { @@ -37,12 +39,12 @@ public Map getDailyDefenseProblem(Map crite final ProblemTier endTier = difficultyRange.getEndDifficulty(); final List dailyDefenseProblems = - problemRepository.getDailyDefenseProblems(ProblemTier.tierRangeOf(startTier, endTier), - randomCriteria.getMinSolvedCount(), - randomCriteria.getMaxSolvedCount(), - pageable); + problemRepository.getDailyDefenseProblems + (ProblemTier.tierRangeOf(startTier, endTier), + randomCriteria.getMinSolvedCount(), + randomCriteria.getMaxSolvedCount(), pageable); - return Map.entry(entry.getKey(), dailyDefenseProblems.get(0)); + return Map.entry(entry.getKey(), dailyDefenseProblems.get(random.nextInt(dailyDefenseProblems.size()))); }) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); } diff --git a/src/main/java/kr/co/morandi/backend/problem_information/domain/model/problem/Problem.java b/src/main/java/kr/co/morandi/backend/problem_information/domain/model/problem/Problem.java index 27c8d072..4be1c74e 100644 --- a/src/main/java/kr/co/morandi/backend/problem_information/domain/model/problem/Problem.java +++ b/src/main/java/kr/co/morandi/backend/problem_information/domain/model/problem/Problem.java @@ -8,6 +8,9 @@ import static kr.co.morandi.backend.problem_information.domain.model.problem.ProblemStatus.INIT; @Entity +@Table(name = "problem", indexes = { + @Index(name = "idx-", columnList = "solvedCount, problemTier, problemStatus") +}) @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Problem extends BaseEntity { diff --git a/src/main/java/kr/co/morandi/backend/problem_information/infrastructure/persistence/problem/ProblemRepository.java b/src/main/java/kr/co/morandi/backend/problem_information/infrastructure/persistence/problem/ProblemRepository.java index 006b61e1..bb915f1f 100644 --- a/src/main/java/kr/co/morandi/backend/problem_information/infrastructure/persistence/problem/ProblemRepository.java +++ b/src/main/java/kr/co/morandi/backend/problem_information/infrastructure/persistence/problem/ProblemRepository.java @@ -14,13 +14,12 @@ public interface ProblemRepository extends JpaRepository { @Query(""" SELECT p FROM Problem p + LEFT JOIN DailyDefenseProblem ddp ON p.problemId = ddp.problem.problemId WHERE p.problemStatus = 'ACTIVE' - AND p.problemTier IN :problemTiers - AND p.solvedCount >= :startSolvedCount - AND p.solvedCount <= :endSolvedCount - AND p NOT IN (SELECT ddp.problem - FROM DailyDefenseProblem ddp) - ORDER BY FUNCTION('RAND') + AND p.problemTier IN :problemTiers + AND p.solvedCount >= :startSolvedCount + AND p.solvedCount <= :endSolvedCount + AND ddp.problem IS NULL """) List getDailyDefenseProblems(List problemTiers, Long startSolvedCount, Long endSolvedCount, Pageable pageable); From e09ae1194257d59091731213dfb4b5804d099d6e Mon Sep 17 00:00:00 2001 From: "aj4941@naver.com" Date: Tue, 20 Aug 2024 15:02:30 +0900 Subject: [PATCH 3/7] =?UTF-8?q?:pencil2:=20Index=20name=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../problem_information/domain/model/problem/Problem.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/kr/co/morandi/backend/problem_information/domain/model/problem/Problem.java b/src/main/java/kr/co/morandi/backend/problem_information/domain/model/problem/Problem.java index 4be1c74e..f0a97bea 100644 --- a/src/main/java/kr/co/morandi/backend/problem_information/domain/model/problem/Problem.java +++ b/src/main/java/kr/co/morandi/backend/problem_information/domain/model/problem/Problem.java @@ -9,7 +9,7 @@ @Entity @Table(name = "problem", indexes = { - @Index(name = "idx-", columnList = "solvedCount, problemTier, problemStatus") + @Index(name = "idx_problem_solvedCount_tier_status", columnList = "solvedCount, problemTier, problemStatus") }) @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) From e286f950810ac0b3496d8f03f3dceae4636c8bb7 Mon Sep 17 00:00:00 2001 From: "aj4941@naver.com" Date: Tue, 20 Aug 2024 15:20:40 +0900 Subject: [PATCH 4/7] =?UTF-8?q?:pencil2:=20=EC=98=A4=EB=8A=98=EC=9D=98=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=EC=A0=95=EB=8B=B5=EC=9E=90=20=EC=88=98=20?= =?UTF-8?q?=EB=B2=94=EC=9C=84=20=EC=9D=BC=EB=B6=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dailydefense/DailyDefenseGenerationService.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/kr/co/morandi/backend/defense_information/domain/service/dailydefense/DailyDefenseGenerationService.java b/src/main/java/kr/co/morandi/backend/defense_information/domain/service/dailydefense/DailyDefenseGenerationService.java index da3ad8d5..c7309df7 100644 --- a/src/main/java/kr/co/morandi/backend/defense_information/domain/service/dailydefense/DailyDefenseGenerationService.java +++ b/src/main/java/kr/co/morandi/backend/defense_information/domain/service/dailydefense/DailyDefenseGenerationService.java @@ -23,11 +23,11 @@ public class DailyDefenseGenerationService { private final DailyDefenseProblemPort dailyDefenseProblemPort; private final DailyDefensePort dailyDefensePort; - private static final Map.Entry PROBLEM_1 = getRandomCriteria(1L, B5, B1, 1000L, 300000L); - private static final Map.Entry PROBLEM_2 = getRandomCriteria(2L, S5, S4, 1000L, 300000L); - private static final Map.Entry PROBLEM_3 = getRandomCriteria(3L, S3, S1, 1000L, 300000L); - private static final Map.Entry PROBLEM_4 = getRandomCriteria(4L, G5, G4, 1000L, 300000L); - private static final Map.Entry PROBLEM_5 = getRandomCriteria(5L, G3, G1, 1000L, 300000L); + private static final Map.Entry PROBLEM_1 = getRandomCriteria(1L, B5, B1, 1000L, 30000L); + private static final Map.Entry PROBLEM_2 = getRandomCriteria(2L, S5, S4, 1000L, 30000L); + private static final Map.Entry PROBLEM_3 = getRandomCriteria(3L, S3, S1, 1000L, 30000L); + private static final Map.Entry PROBLEM_4 = getRandomCriteria(4L, G5, G4, 1000L, 30000L); + private static final Map.Entry PROBLEM_5 = getRandomCriteria(5L, G3, G1, 1000L, 30000L); private static final String POSTFIX = "%d월 %d일 오늘의 문제"; @Transactional From c95aec1265a5c5b4403b3e5ae4af070157b15d05 Mon Sep 17 00:00:00 2001 From: "aj4941@naver.com" Date: Wed, 21 Aug 2024 13:24:11 +0900 Subject: [PATCH 5/7] =?UTF-8?q?:pencil2:=20Random=EC=9D=84=20ThreadLocalRa?= =?UTF-8?q?ndom=20=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/dailydefense/DailyDefenseProblemAdapter.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/kr/co/morandi/backend/defense_information/infrastructure/adapter/dailydefense/DailyDefenseProblemAdapter.java b/src/main/java/kr/co/morandi/backend/defense_information/infrastructure/adapter/dailydefense/DailyDefenseProblemAdapter.java index a6b2f760..77ab100c 100644 --- a/src/main/java/kr/co/morandi/backend/defense_information/infrastructure/adapter/dailydefense/DailyDefenseProblemAdapter.java +++ b/src/main/java/kr/co/morandi/backend/defense_information/infrastructure/adapter/dailydefense/DailyDefenseProblemAdapter.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.Map; import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; import java.util.stream.Collectors; @Component @@ -29,7 +30,6 @@ public class DailyDefenseProblemAdapter implements DailyDefenseProblemPort { public Map getDailyDefenseProblem(Map criteria) { Pageable pageable = PageRequest.of(0, 50); - Random random = new Random(); return criteria.entrySet().stream() .map(entry -> { @@ -44,7 +44,8 @@ public Map getDailyDefenseProblem(Map crite randomCriteria.getMinSolvedCount(), randomCriteria.getMaxSolvedCount(), pageable); - return Map.entry(entry.getKey(), dailyDefenseProblems.get(random.nextInt(dailyDefenseProblems.size()))); + int randomNum = ThreadLocalRandom.current().nextInt(0, dailyDefenseProblems.size()); + return Map.entry(entry.getKey(), dailyDefenseProblems.get(randomNum)); }) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); } From 353417ab7fce001998be40e9c8d0a0203a4588e3 Mon Sep 17 00:00:00 2001 From: "aj4941@naver.com" Date: Wed, 21 Aug 2024 13:38:22 +0900 Subject: [PATCH 6/7] =?UTF-8?q?:pencil2:=20Random=20=EB=B3=80=EC=88=98?= =?UTF-8?q?=EB=A5=BC=20SecureRandom=20=ED=98=95=ED=83=9C=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/dailydefense/DailyDefenseProblemAdapter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/kr/co/morandi/backend/defense_information/infrastructure/adapter/dailydefense/DailyDefenseProblemAdapter.java b/src/main/java/kr/co/morandi/backend/defense_information/infrastructure/adapter/dailydefense/DailyDefenseProblemAdapter.java index 77ab100c..b431bb15 100644 --- a/src/main/java/kr/co/morandi/backend/defense_information/infrastructure/adapter/dailydefense/DailyDefenseProblemAdapter.java +++ b/src/main/java/kr/co/morandi/backend/defense_information/infrastructure/adapter/dailydefense/DailyDefenseProblemAdapter.java @@ -12,6 +12,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Component; +import java.security.SecureRandom; import java.util.List; import java.util.Map; import java.util.Random; @@ -44,7 +45,7 @@ public Map getDailyDefenseProblem(Map crite randomCriteria.getMinSolvedCount(), randomCriteria.getMaxSolvedCount(), pageable); - int randomNum = ThreadLocalRandom.current().nextInt(0, dailyDefenseProblems.size()); + int randomNum = new SecureRandom().nextInt(dailyDefenseProblems.size()); return Map.entry(entry.getKey(), dailyDefenseProblems.get(randomNum)); }) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); From 11c59bd92d5b6e96f67a3c4bf72767771b202e19 Mon Sep 17 00:00:00 2001 From: "aj4941@naver.com" Date: Thu, 22 Aug 2024 22:16:53 +0900 Subject: [PATCH 7/7] =?UTF-8?q?:heavy=5Fplus=5Fsign:=20H2=20Database?= =?UTF-8?q?=EB=A5=BC=20=ED=99=95=EC=9D=B8=ED=95=98=EA=B8=B0=20=EC=9C=84?= =?UTF-8?q?=ED=95=B4=20localhost:9080=EB=A1=9C=20=EB=B3=BC=20=EC=88=98=20?= =?UTF-8?q?=EC=9E=88=EB=8F=84=EB=A1=9D=20=EA=B5=AC=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 13 ++++--- .../backend/common/config/H2Config.java | 35 +++++++++++++++++++ .../backend/common/config/H2Properties.java | 16 +++++++++ 3 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 src/main/java/kr/co/morandi/backend/common/config/H2Config.java create mode 100644 src/main/java/kr/co/morandi/backend/common/config/H2Properties.java diff --git a/build.gradle b/build.gradle index 59f169d8..01d28d45 100644 --- a/build.gradle +++ b/build.gradle @@ -3,16 +3,10 @@ plugins { id 'org.springframework.boot' version '3.2.2' id 'io.spring.dependency-management' version '1.1.4' id 'org.asciidoctor.jvm.convert' version '3.3.2' -} -plugins { id "org.sonarqube" version "4.4.1.3373" -} - -plugins { id 'jacoco' } - def jacocoDir = layout.buildDirectory.dir("reports/") def QDomains = [] for (qPattern in '*.QA'..'*.QZ') { // qPattern = '*.QA', '*.QB', ... '*.QZ' @@ -92,10 +86,15 @@ dependencies { // Jsoup implementation 'org.jsoup:jsoup:1.16.1' + // h2 + implementation 'com.h2database:h2' + implementation 'org.springframework.boot:spring-boot-starter-jdbc' + runtimeOnly 'com.h2database:h2' + implementation 'org.springframework.boot:spring-boot-devtools' + // Pusher java client implementation group: 'com.pusher', name: 'pusher-java-client', version: '2.4.4' - // WebFlux (WebClient) implementation 'org.springframework.boot:spring-boot-starter-webflux' diff --git a/src/main/java/kr/co/morandi/backend/common/config/H2Config.java b/src/main/java/kr/co/morandi/backend/common/config/H2Config.java new file mode 100644 index 00000000..b33d555f --- /dev/null +++ b/src/main/java/kr/co/morandi/backend/common/config/H2Config.java @@ -0,0 +1,35 @@ +package kr.co.morandi.backend.common.config; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.h2.tools.Server; +import org.springframework.context.annotation.Profile; +import org.springframework.context.event.ContextClosedEvent; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +import java.sql.SQLException; + +@Component +@Profile("test") +@RequiredArgsConstructor +@Slf4j +public class H2Config { + + // '/h2-console' 시 webflux로 인해 localhost:9080으로 접속해서 DB 확인해야 함 + private final H2Properties properties; + private Server webServer; + + @EventListener + public void start(ContextRefreshedEvent event) throws SQLException { + log.info("h2 port : {}", properties.getPort()); + this.webServer = Server.createWebServer("-webPort", properties.getPort(), "-tcpAllowOthers").start(); + } + + @EventListener + public void stop(ContextClosedEvent event){ + this.webServer.stop(); + + } +} diff --git a/src/main/java/kr/co/morandi/backend/common/config/H2Properties.java b/src/main/java/kr/co/morandi/backend/common/config/H2Properties.java new file mode 100644 index 00000000..5fecc3a3 --- /dev/null +++ b/src/main/java/kr/co/morandi/backend/common/config/H2Properties.java @@ -0,0 +1,16 @@ +package kr.co.morandi.backend.common.config; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; + +@Getter +@Setter +@ConfigurationProperties("spring.h2.console") +@Configuration +@Profile("test") +public class H2Properties { + private String port; +}