From 94ca74ac9ae82805393ac2cf0c30b369ce9d64f8 Mon Sep 17 00:00:00 2001 From: Park Yun Chan Date: Tue, 24 Sep 2024 16:35:18 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EC=9C=A0=ED=9A=A8=ED=95=98=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EC=9D=80=20FCM=ED=86=A0=ED=81=B0=20=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=20(#276)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/FcmNotificationService.java | 7 ++-- .../domain/fcm/dao/FcmTokenRepository.java | 2 + .../sqs/application/SqsMessageService.java | 41 ++++++++++++------- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/depromeet/stonebed/domain/fcm/application/FcmNotificationService.java b/src/main/java/com/depromeet/stonebed/domain/fcm/application/FcmNotificationService.java index 4adb016c..aebd82e7 100644 --- a/src/main/java/com/depromeet/stonebed/domain/fcm/application/FcmNotificationService.java +++ b/src/main/java/com/depromeet/stonebed/domain/fcm/application/FcmNotificationService.java @@ -28,13 +28,14 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; import lombok.RequiredArgsConstructor; -import org.springdoc.core.parsers.ReturnTypeParser; +import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +@Slf4j @Service @RequiredArgsConstructor @Transactional @@ -53,7 +54,7 @@ public class FcmNotificationService { private static final long FIRST_BOOST_THRESHOLD = 1; private static final long POPULAR_THRESHOLD = 1000; private static final long SUPER_POPULAR_THRESHOLD = 5000; - private final ReturnTypeParser genericReturnTypeParser; + private static final int BATCH_SIZE = 10; public void saveNotification( FcmNotificationType type, @@ -271,7 +272,7 @@ private List buildNotificationList( } public void sendAndNotifications(String title, String message, List tokens) { - List> batches = createBatches(tokens, 10); + List> batches = createBatches(tokens, BATCH_SIZE); String deepLink = FcmNotification.generateDeepLink(FcmNotificationType.MISSION, null, null); diff --git a/src/main/java/com/depromeet/stonebed/domain/fcm/dao/FcmTokenRepository.java b/src/main/java/com/depromeet/stonebed/domain/fcm/dao/FcmTokenRepository.java index 017b1e86..f89f3c32 100644 --- a/src/main/java/com/depromeet/stonebed/domain/fcm/dao/FcmTokenRepository.java +++ b/src/main/java/com/depromeet/stonebed/domain/fcm/dao/FcmTokenRepository.java @@ -17,4 +17,6 @@ public interface FcmTokenRepository List findAllByMemberStatus(MemberStatus status); List findAllByUpdatedAtBefore(LocalDateTime cutoffDate); + + void deleteByToken(String token); } diff --git a/src/main/java/com/depromeet/stonebed/domain/sqs/application/SqsMessageService.java b/src/main/java/com/depromeet/stonebed/domain/sqs/application/SqsMessageService.java index a63fd0c6..7fd176a5 100644 --- a/src/main/java/com/depromeet/stonebed/domain/sqs/application/SqsMessageService.java +++ b/src/main/java/com/depromeet/stonebed/domain/sqs/application/SqsMessageService.java @@ -1,11 +1,11 @@ package com.depromeet.stonebed.domain.sqs.application; +import com.depromeet.stonebed.domain.fcm.dao.FcmTokenRepository; import com.depromeet.stonebed.domain.fcm.domain.FcmMessage; import com.depromeet.stonebed.infra.properties.SqsProperties; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.ArrayList; import java.util.List; -import java.util.UUID; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -29,6 +29,7 @@ public class SqsMessageService { private final SqsProperties sqsProperties; private final ObjectMapper objectMapper; + private final FcmTokenRepository fcmTokenRepository; public void sendMessage(Object message) { try { @@ -49,13 +50,14 @@ public void sendMessage(Object message) { public void sendBatchMessages( List tokens, String title, String message, String deepLink) { List entries = new ArrayList<>(); + List failedTokens = new ArrayList<>(); for (String token : tokens) { try { FcmMessage fcmMessage = FcmMessage.of(title, message, token, deepLink); String messageBody = objectMapper.writeValueAsString(fcmMessage); SendMessageBatchRequestEntry entry = SendMessageBatchRequestEntry.builder() - .id(UUID.randomUUID().toString()) + .id(token) .messageBody(messageBody) .build(); entries.add(entry); @@ -64,25 +66,34 @@ public void sendBatchMessages( } } - SendMessageBatchRequest batchRequest = - SendMessageBatchRequest.builder() - .queueUrl(sqsProperties.queueUrl()) - .entries(entries) - .build(); + if (!entries.isEmpty()) { + SendMessageBatchRequest batchRequest = + SendMessageBatchRequest.builder() + .queueUrl(sqsProperties.queueUrl()) + .entries(entries) + .build(); - try { - SendMessageBatchResponse batchResponse = sqsClient.sendMessageBatch(batchRequest); + try { + SendMessageBatchResponse batchResponse = sqsClient.sendMessageBatch(batchRequest); - // 실패한 메시지 처리 - List failedMessages = batchResponse.failed(); - if (!failedMessages.isEmpty()) { + // 실패한 메시지 처리 + List failedMessages = batchResponse.failed(); for (BatchResultErrorEntry failed : failedMessages) { log.error("메시지 전송 실패, ID {}: {}", failed.id(), failed.message()); + failedTokens.add(failed.id()); } - } - } catch (Exception e) { - log.error("SQS 배치 메시지 전송 실패: {}", e.getMessage()); + // 실패한 토큰 삭제 등의 후속 작업 + for (String failedToken : failedTokens) { + fcmTokenRepository.deleteByToken(failedToken); + log.info("비활성화된 FCM 토큰 삭제: {}", failedToken); + } + + } catch (Exception e) { + log.error("SQS 배치 메시지 전송 실패: {}", e.getMessage()); + } + } else { + log.warn("전송할 메시지가 없습니다."); } } }