Skip to content

Commit

Permalink
fix: 샵 좋아요/좋아요 취소 이벤트 중복 여부를 api 서버에서 처리하지 않도록 수정
Browse files Browse the repository at this point in the history
sssukho committed Jan 10, 2025

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent d8a8aa2 commit 7177308
Showing 3 changed files with 16 additions and 70 deletions.
Original file line number Diff line number Diff line change
@@ -63,10 +63,9 @@ public ResponseMessage findShopList(@RequestParam(name = "type") final String se
* Shop 좋아요 이벤트 producer
*/
@PostMapping("/v1/shops/likes/{id}")
public DeferredResult<?> likeShop(@PathVariable(value = "id") @NotBlank final String shopId) {
final DeferredResult<Object> deferredResult = new DeferredResult<>();
shopService.produceShopLikeEvent(deferredResult, shopId, "[email protected]");
return deferredResult;
@ResponseStatus(code = HttpStatus.OK)
public void likeShop(@PathVariable(value = "id") @NotBlank final String shopId) {
shopService.produceShopLikeEvent(shopId, "[email protected]");
}

/**
@@ -82,10 +81,9 @@ public void batchShopLikes(@Valid @RequestBody final List<ShopLikeEvent> shopLik
* Shop 좋아요 취소 이벤트 producer
*/
@DeleteMapping("/v1/shops/likes/{id}")
public DeferredResult<?> cancelLikeShop(@PathVariable(value = "id") @NotBlank final String shopId) {
final DeferredResult<Object> deferredResult = new DeferredResult<>();
shopService.produceShopLikeCancelEvent(deferredResult, shopId, "[email protected]");
return deferredResult;
@ResponseStatus(code = HttpStatus.OK)
public void cancelLikeShop(@PathVariable(value = "id") @NotBlank final String shopId) {
shopService.produceShopLikeCancelEvent(shopId, "[email protected]");
}

/**
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.beautify_project.bp_app_api.service;

import com.beautify_project.bp_app_api.dto.common.ErrorResponseMessage;
import com.beautify_project.bp_app_api.dto.common.ErrorResponseMessage.ErrorCode;
import com.beautify_project.bp_app_api.dto.common.ResponseMessage;
import com.beautify_project.bp_app_api.dto.event.ShopLikeCancelEvent;
@@ -29,13 +28,9 @@
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.async.DeferredResult;

@Service
@Slf4j
@@ -144,64 +139,13 @@ public Shop findShopById(final @NotBlank String shopId) {
}

@Async(value = "ioBoundExecutor")
public void produceShopLikeEvent(final DeferredResult<Object> deferredResult,
final String shopId, final String memberEmail) {

if (!validateShopLikeEventRequest(shopId, memberEmail)) {
final ErrorResponseMessage errorResponseMessage = ErrorResponseMessage.createErrorMessage(
ErrorCode.SL001);
deferredResult.setErrorResult(
new ResponseEntity<>(errorResponseMessage, errorResponseMessage.getHttpStatus()));
return;
}

public void produceShopLikeEvent(final String shopId, final String memberEmail) {
kafkaEventProducer.publishShopLikeEvent(new ShopLikeEvent(shopId, memberEmail));
deferredResult.setResult(
new ResponseEntity<>(HttpStatusCode.valueOf(HttpStatus.NO_CONTENT.value())));
}

private boolean validateShopLikeEventRequest(final String shopId, final String memberEmail) {
if (!shopRepository.existsById(shopId)) {
log.error("Failed to find shop: shopId - {}", shopId);
return false;
}

if (shopLikeService.isLikePushed(shopId, memberEmail)) {
log.error("Like is already pushed: shopId - {} memberEmail - {}", shopId, memberEmail);
return false;
}

return true;
}

@Async(value = "ioBoundExecutor")
public void produceShopLikeCancelEvent(final DeferredResult<Object> deferredResult,
final String shopId, final String memberEmail) {

if (!validateShopLikeCancelEventRequest(shopId, memberEmail)) {
final ErrorResponseMessage errorResponseMessage = ErrorResponseMessage.createErrorMessage(
ErrorCode.SL002);
deferredResult.setErrorResult(
new ResponseEntity<>(errorResponseMessage, errorResponseMessage.getHttpStatus()));
return;
}

public void produceShopLikeCancelEvent(final String shopId, final String memberEmail) {
kafkaEventProducer.publishShopLikeCancelEvent(new ShopLikeCancelEvent(shopId, memberEmail));
deferredResult.setResult(
new ResponseEntity<>(HttpStatusCode.valueOf(HttpStatus.NO_CONTENT.value())));
}

private boolean validateShopLikeCancelEventRequest(final String shopId, final String memberEmail) {
if (!shopRepository.existsById(shopId)) {
log.error("Failed to find shop: shopId - {}", shopId);
return false;
}

if (!shopLikeService.isLikePushed(shopId, memberEmail)) {
return false;
}

return true;
}

@Transactional(rollbackFor = Exception.class)
Original file line number Diff line number Diff line change
@@ -15,10 +15,14 @@ public class ShopLikeCancelEventConsumer {

private final ShopLikeCancelApi shopLikeCancelApi;

@KafkaListener(
topics = "shop-like-cancel",
groupId = "shop-like-cancel-event-consumer-group",
containerFactory = "shopLikeCancelEventListenerContainerFactory")
// @KafkaListener(
// topics = "shop-like-cancel",
// groupId = "shop-like-cancel-event-consumer-group",
// containerFactory = "shopLikeCancelEventListenerContainerFactory")
@KafkaListener(
topics = "#{kafkaConsumerConfigProperties.topic['SHOP-LIKE-CANCEL-EVENT'].topicName}",
groupId = "#{kafkaConsumerConfigProperties.topic['SHOP-LIKE-CANCEL-EVENT'].groupId}",
containerFactory = "shopLikeCancelEventListenerContainerFactory")
public void listenShopLikeCancelEvent(final List<ShopLikeCancelEvent> events) {
// TODO: consume 은 성공하였으나 외부 api 호출 실패시에 대한 예외 처리 추가 필요
log.debug("event consumed: {}", events.toString());

0 comments on commit 7177308

Please sign in to comment.