From 35ee9780c92e6487ca6f4a23fd67634914f7844c Mon Sep 17 00:00:00 2001 From: kimsuyeondev Date: Sun, 7 Jul 2024 01:50:08 +0900 Subject: [PATCH 1/6] =?UTF-8?q?#39=20=EC=84=9C=EB=B9=84=EC=8A=A4=20Complet?= =?UTF-8?q?ableFuture=20=EC=B6=94=EA=B0=80,=20=EC=A0=95=EC=A0=81=EB=A9=94?= =?UTF-8?q?=EC=86=8C=EB=93=9C=EB=84=A4=EC=9D=B4=EB=B0=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/controller/GoodsController.java | 39 +++++++------------ .../com/cosmetics/config/AsyncConfig.java | 7 ++++ .../domain/goods/dto/GoodsManagement.java | 2 +- .../goods/dto/GoodsManagementRequest.java | 2 +- .../goods/dto/GoodsManagementResponse.java | 2 +- .../domain/goods/service/GoodsService.java | 33 +++++++++------- 6 files changed, 43 insertions(+), 42 deletions(-) diff --git a/module-api/src/main/java/com/cosmetics/api/controller/GoodsController.java b/module-api/src/main/java/com/cosmetics/api/controller/GoodsController.java index 7ff54f9..a988017 100644 --- a/module-api/src/main/java/com/cosmetics/api/controller/GoodsController.java +++ b/module-api/src/main/java/com/cosmetics/api/controller/GoodsController.java @@ -25,55 +25,46 @@ public class GoodsController { @GetMapping(value = "/{goodsNo}") public CompletableFuture findGoods(@PathVariable Long goodsNo) { - - CompletableFuture goodsResponseFuture = CompletableFuture.supplyAsync(() -> { - log.error("findGoodsThread = {}", Thread.currentThread().getName()); - GoodsManagement goodsManagement = goodsService.findByGoodsNo(goodsNo); - return GoodsManagementResponse.toResponseDto(goodsManagement); - - }).thenApplyAsync( //callback + return goodsService.findByGoodsNo(goodsNo).thenApplyAsync(goodsManagement -> { + return GoodsManagementResponse.fromDto(goodsManagement); + }).thenApplyAsync( (GoodsManagementResponse response) -> { log.error("findGoods thenApplayAsync= {}", Thread.currentThread().getName()); response.updateSuccess("0000", "조회성공"); return response; } ); - - return goodsResponseFuture; } @PostMapping @ResponseStatus(HttpStatus.CREATED) public CompletableFuture registerGoods(@RequestBody @Valid GoodsManagementRequest goodsManagementRequest) throws ExecutionException, InterruptedException { - - CompletableFuture goodsResponseFuture = CompletableFuture.supplyAsync(() -> { - log.error("goodsName = {}, registerGoodsThread = {}", goodsManagementRequest.getGoodsNm(), Thread.currentThread().getName()); //ForkJoinPool.commonPool-worker-1 - return goodsService.save(goodsManagementRequest.toServiceDto()); //등록 - - }).thenApplyAsync( - //dto -> + CompletableFuture goodsResponseFuture = goodsService.save(goodsManagementRequest.toDto()).thenApplyAsync( (goodsManagement) -> { - log.error("goodsName = {}, goodsNo = {}", goodsManagementRequest.getGoodsNm(), goodsManagement.getGoodsNo()); + log.error("saveAfter goodsName = {}, goodsNo = {}", goodsManagement.getGoodsNm(), goodsManagement.getGoodsNo()); log.error("registerGoodsThread thenApplyAsync = {}", Thread.currentThread().getName()); //ForkJoinPool.commonPool-worker-1 - GoodsManagementResponse response = GoodsManagementResponse.toResponseDto(goodsManagement); + GoodsManagementResponse response = GoodsManagementResponse.fromDto(goodsManagement); response.updateSuccess("0000", "등록성공"); return response; } + ).thenApplyAsync( + (response) -> { + if("0000".equals(response.getResultCode())){ + smsService.smsMessage(response.getGoodsNo()); //Cosmetics-Thread-Pool1 + } + return response; + } ); - - //등록에 성공하면 메세지를 보낸다고 가정 - if ("0000".equals(goodsResponseFuture.get().getResultCode())) { - smsService.smsMessage(goodsResponseFuture.get().getGoodsNo()); //Cosmetics-Thread-Pool1 - } return goodsResponseFuture; } + @DeleteMapping(value = "/{goodsNo}") public GoodsManagementResponse deleteGoods(@PathVariable Long goodsNo) { log.error("deleteGoods : {}", goodsNo); GoodsManagement goodsManagement = goodsService.deleteByGoodsNo(goodsNo); //dto -> responseDto - GoodsManagementResponse responseGoodsManagement = GoodsManagementResponse.toResponseDto(goodsManagement); + GoodsManagementResponse responseGoodsManagement = GoodsManagementResponse.fromDto(goodsManagement); responseGoodsManagement.updateSuccess("0000", "삭제성공"); return responseGoodsManagement; } diff --git a/module-api/src/main/java/com/cosmetics/config/AsyncConfig.java b/module-api/src/main/java/com/cosmetics/config/AsyncConfig.java index 8792535..ff7612c 100644 --- a/module-api/src/main/java/com/cosmetics/config/AsyncConfig.java +++ b/module-api/src/main/java/com/cosmetics/config/AsyncConfig.java @@ -1,6 +1,9 @@ package com.cosmetics.config; +import com.cosmetics.api.exception.handler.CosmeticsAsyncExceptionHandler; +import com.cosmetics.api.exception.handler.CosmeticsExceptionHandler; import lombok.extern.slf4j.Slf4j; +import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.AsyncConfigurer; import org.springframework.scheduling.annotation.EnableAsync; @@ -30,4 +33,8 @@ public Executor getAsyncExecutor() { //상황에 따라 최소 스레드 수 최대 스레드 수 대기 큐의 크기를 조절해야하는데 그 상황이 어떤 상황에 따라 어떤 걸 보고 어떻게 지정해야할 지 //궁금합니다 } + @Override + public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { + return new CosmeticsAsyncExceptionHandler(); + } } diff --git a/module-domain/src/main/java/com/cosmetics/domain/goods/dto/GoodsManagement.java b/module-domain/src/main/java/com/cosmetics/domain/goods/dto/GoodsManagement.java index 8525839..c21d690 100644 --- a/module-domain/src/main/java/com/cosmetics/domain/goods/dto/GoodsManagement.java +++ b/module-domain/src/main/java/com/cosmetics/domain/goods/dto/GoodsManagement.java @@ -69,7 +69,7 @@ public GoodsManagement(Long goodsNo, this.addImage = addImage; } - public static GoodsManagement toDto(GoodsManagementEntity goodsManagementEntity) { + public static GoodsManagement fromEntity(GoodsManagementEntity goodsManagementEntity) { return GoodsManagement.builder() .goodsNo(goodsManagementEntity.getGoodsNo()) .goodsNm(goodsManagementEntity.getGoodsNm()) diff --git a/module-domain/src/main/java/com/cosmetics/domain/goods/dto/GoodsManagementRequest.java b/module-domain/src/main/java/com/cosmetics/domain/goods/dto/GoodsManagementRequest.java index 6344c58..0ce1daf 100644 --- a/module-domain/src/main/java/com/cosmetics/domain/goods/dto/GoodsManagementRequest.java +++ b/module-domain/src/main/java/com/cosmetics/domain/goods/dto/GoodsManagementRequest.java @@ -95,7 +95,7 @@ public List toGoodsItemManagementList(List new IllegalArgumentException("상품이 존재하지 않습니다.")); - //entity -> dto - return GoodsManagement.toDto(goodsManagementEntity); + public CompletableFuture findByGoodsNo(Long goodsNo) { + CompletableFuture goodsManageFuture = CompletableFuture.supplyAsync(() -> { + log.error("GoodsService Thread = {}", Thread.currentThread().getName()); + GoodsManagementEntity goodsManagementEntity = goodsRepository.findByGoodsNo(goodsNo).orElseThrow(() -> new IllegalArgumentException("상품이 존재하지 않습니다.")); + return GoodsManagement.fromEntity(goodsManagementEntity); + }); + return goodsManageFuture; } @Transactional - public GoodsManagement save(GoodsManagement goodsManagement) { - //Service단은 따로 작업을 안했는데 이게 맞을까요? - GoodsManagementEntity resultGoodsManagementEntity = goodsRepository.save(goodsManagement.toEntity()); - - //entity -> dto - return GoodsManagement.toDto(resultGoodsManagementEntity); + public CompletableFuture save(GoodsManagement goodsManagement) { + CompletableFuture goodsManageFuture = CompletableFuture.supplyAsync(() -> { + log.error("GoodsService Thread = {}", Thread.currentThread().getName()); + GoodsManagementEntity resultGoodsManagementEntity = goodsRepository.save(goodsManagement.toEntity()); + return GoodsManagement.fromEntity(resultGoodsManagementEntity); + }); + return goodsManageFuture; } @Transactional public GoodsManagement deleteByGoodsNo(Long goodsNo) { GoodsManagementEntity goodsManagementEntity = goodsRepository.findByGoodsNo(goodsNo).orElseThrow(() -> new IllegalArgumentException("상품이 존재하지 않습니다.")); long deleteCnt = goodsRepository.deleteByGoodsNo(goodsNo); - //entity -> dto - return GoodsManagement.toDto(goodsManagementEntity); + return GoodsManagement.fromEntity(goodsManagementEntity); } } From 8391a72f58f3ccd84689990b17b585be10233f70 Mon Sep 17 00:00:00 2001 From: kimsuyeondev Date: Sun, 7 Jul 2024 01:58:11 +0900 Subject: [PATCH 2/6] =?UTF-8?q?#39=20=EC=84=9C=EB=B9=84=EC=8A=A4=20Complet?= =?UTF-8?q?ableFuture=20=EC=B6=94=EA=B0=80,=20=EC=A0=95=EC=A0=81=EB=A9=94?= =?UTF-8?q?=EC=86=8C=EB=93=9C=EB=84=A4=EC=9D=B4=EB=B0=8D=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/db/mysql/init/init.sql | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docker/db/mysql/init/init.sql b/docker/db/mysql/init/init.sql index 41dccec..caa6398 100644 --- a/docker/db/mysql/init/init.sql +++ b/docker/db/mysql/init/init.sql @@ -73,13 +73,6 @@ select * from pv_goods; select * from pv_item; select * from pv_goods where goods_no =1; -select * from od_order; -select * from od_order_dtl; -select * from od_order_deli; -select * from od_order_pay; -select * from od_order_goods; -select * from od_order_bene; - /* 주문자 관리 기본 정보 마스터 */ CREATE TABLE IF NOT EXISTS od_order( order_no INT(11) NOT NULL AUTO_INCREMENT, @@ -89,14 +82,14 @@ CREATE TABLE IF NOT EXISTS od_order( cell_no VARCHAR(30) NOT NULL, insert_dtime DATETIME DEFAULT now(), update_dtime DATETIME DEFAULT now(), - CONSTRAINT od_ord_master_pk PRIMARY KEY(order_no), + CONSTRAINT od_ord_master_pk PRIMARY KEY(order_no) ); /* 상품단위 주문 정보 */ CREATE TABLE IF NOT EXISTS od_order_dtl( order_no INT(11) NOT NULL AUTO_INCREMENT, - order_step INT(11) NOT NULL AUTO_INCREMENT, /* 단계 주문/취소/반품/ */ - order_status /*주문상태 결제대기 결제중 */ + order_step VARCHAR(4) NOT NULL, /* 단계 주문/취소/반품/ */ + order_status VARCHAR(4) NOT NULL, /*주문상태 결제대기 결제중 */ goods_no INT(11) NOT NULL, goods_nm VARCHAR(30) NOT NULL, item_no INT(11) NOT NULL, @@ -113,8 +106,15 @@ CREATE TABLE IF NOT EXISTS od_order_dtl( CONSTRAINT od_order_dtl_pk PRIMARY KEY(order_no), foreign key (order_no) references od_order(order_no) ); - +/* +select * from od_order; +select * from od_order_dtl; +select * from od_order_deli; +select * from od_order_pay; +select * from od_order_goods; +select * from od_order_bene; drop table pv_item; drop table pv_goods;commit; + */ select count(*) over(), a.* from pv_goods a ; select a.goods_nm ,b.item_nm,a.* from pv_goods a, pv_item b where a.goods_no = b.goods_no ; From 04aa94fbb097ec9822e45c4f9eb4d7918750b010 Mon Sep 17 00:00:00 2001 From: kimsuyeondev Date: Sun, 7 Jul 2024 16:35:33 +0900 Subject: [PATCH 3/6] #39 --- .../com/cosmetics/api/application/GoodsApiApplicationTest.java | 2 +- .../test/java/com/cosmetics/controller/VendControllerTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/module-api/src/test/java/com/cosmetics/api/application/GoodsApiApplicationTest.java b/module-api/src/test/java/com/cosmetics/api/application/GoodsApiApplicationTest.java index 0dc5fae..a5f8894 100644 --- a/module-api/src/test/java/com/cosmetics/api/application/GoodsApiApplicationTest.java +++ b/module-api/src/test/java/com/cosmetics/api/application/GoodsApiApplicationTest.java @@ -112,7 +112,7 @@ private static GoodsManagementRequest requestGoods(int i) { String url = "http://localhost:" + port + "/v1/goods/{goodsNo}"; ResponseEntity responseEntity = testRestTemplate.getForEntity(url, GoodsManagementResponse.class, goodsNo); assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(responseEntity.getBody().getGoodsNm()).isEqualTo("닥터스킨"); + assertThat(responseEntity.getBody().getGoodsNm()).isEqualTo("닥터스"); } @DisplayName("상품 삭제") diff --git a/module-api/src/test/java/com/cosmetics/controller/VendControllerTest.java b/module-api/src/test/java/com/cosmetics/controller/VendControllerTest.java index 7de659f..eb5cde6 100644 --- a/module-api/src/test/java/com/cosmetics/controller/VendControllerTest.java +++ b/module-api/src/test/java/com/cosmetics/controller/VendControllerTest.java @@ -41,7 +41,7 @@ public void validVendorTest() throws Exception { .andDo(print()) .andExpect(jsonPath("errorCode").value("INVALID_PARAMETER")) .andExpect(jsonPath("errorMessage").value("유효하지 않는 값입니다")) - .andExpect(jsonPath("$.fieldErrorList[0].field").value(anyOf(is("vendorNm"), is("postNo")))) + .andExpect(jsonPath("$.fieldErrorList[0].field").value(anyOf(is("vendorNm"), is("postNo"), is("addr")))) .andExpect(jsonPath("$.fieldErrorList[0].message").value("must not be blank")); } From 5a97bb0992c06db026fc4314fd43e3bccca59d31 Mon Sep 17 00:00:00 2001 From: kimsuyeondev Date: Sun, 7 Jul 2024 18:45:59 +0900 Subject: [PATCH 4/6] #39 --- .../java/com/cosmetics/domain/goods/service/GoodsService.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/module-domain/src/main/java/com/cosmetics/domain/goods/service/GoodsService.java b/module-domain/src/main/java/com/cosmetics/domain/goods/service/GoodsService.java index 2f61534..34dcbbb 100644 --- a/module-domain/src/main/java/com/cosmetics/domain/goods/service/GoodsService.java +++ b/module-domain/src/main/java/com/cosmetics/domain/goods/service/GoodsService.java @@ -20,12 +20,11 @@ public class GoodsService { @Transactional public CompletableFuture findByGoodsNo(Long goodsNo) { - CompletableFuture goodsManageFuture = CompletableFuture.supplyAsync(() -> { + return CompletableFuture.supplyAsync(() -> { log.error("GoodsService Thread = {}", Thread.currentThread().getName()); GoodsManagementEntity goodsManagementEntity = goodsRepository.findByGoodsNo(goodsNo).orElseThrow(() -> new IllegalArgumentException("상품이 존재하지 않습니다.")); return GoodsManagement.fromEntity(goodsManagementEntity); }); - return goodsManageFuture; } @Transactional From b0f1f5272a49024479faaddf344266a863a75093 Mon Sep 17 00:00:00 2001 From: kimsuyeondev Date: Sun, 7 Jul 2024 19:01:02 +0900 Subject: [PATCH 5/6] #39 --- .../java/com/cosmetics/domain/goods/service/GoodsService.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/module-domain/src/main/java/com/cosmetics/domain/goods/service/GoodsService.java b/module-domain/src/main/java/com/cosmetics/domain/goods/service/GoodsService.java index 34dcbbb..d27c600 100644 --- a/module-domain/src/main/java/com/cosmetics/domain/goods/service/GoodsService.java +++ b/module-domain/src/main/java/com/cosmetics/domain/goods/service/GoodsService.java @@ -3,12 +3,11 @@ import com.cosmetics.domain.goods.dto.GoodsManagement; import com.cosmetics.domain.goods.entity.GoodsManagementEntity; import com.cosmetics.domain.goods.repository.GoodsRepository; -import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; import java.util.concurrent.CompletableFuture; @Service From 7d98c2f26768a1790e5ed4c498b3cc66cdc78d5c Mon Sep 17 00:00:00 2001 From: kimsuyeondev Date: Mon, 8 Jul 2024 00:34:34 +0900 Subject: [PATCH 6/6] #39 --- .../com/cosmetics/domain/goods/dto/GoodsManagementResponse.java | 1 - 1 file changed, 1 deletion(-) diff --git a/module-domain/src/main/java/com/cosmetics/domain/goods/dto/GoodsManagementResponse.java b/module-domain/src/main/java/com/cosmetics/domain/goods/dto/GoodsManagementResponse.java index ec397b3..27b71ce 100644 --- a/module-domain/src/main/java/com/cosmetics/domain/goods/dto/GoodsManagementResponse.java +++ b/module-domain/src/main/java/com/cosmetics/domain/goods/dto/GoodsManagementResponse.java @@ -15,7 +15,6 @@ @NoArgsConstructor @JsonInclude(JsonInclude.Include.NON_NULL) public class GoodsManagementResponse extends ResponseDto { - private Long goodsNo; private String category; private String goodsNm;