From cf0532bd6971f4f4ffa84dba5d1de38079eabea7 Mon Sep 17 00:00:00 2001 From: hi-june <98803599+hi-june@users.noreply.github.com> Date: Sat, 3 Feb 2024 23:24:32 +0900 Subject: [PATCH] =?UTF-8?q?Refactor/#35=20=ED=8C=94=EB=A1=9C=EC=9A=B0=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=EC=9D=98=20=EB=A9=94=EC=9D=B8=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=EA=B3=BC=20=ED=91=B8=EC=8B=9C=20=EC=95=8C=EB=A6=BC=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=EC=9D=84=20event=20=EC=A0=81=EC=9A=A9=20?= =?UTF-8?q?=EB=B0=8F=20=EB=B9=84=EB=8F=99=EA=B8=B0=20=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?(#36)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 팔로우 신청 및 수락용 event 추가 * feat: push 알림 이벤트용 리스너 추가 * refactor: 푸시 알림 이벤트를 발행하도록 수정 --- .../friend/event/FriendAcceptPushEvent.java | 11 ++ .../friend/event/FriendRequestPushEvent.java | 11 ++ .../friend/event/PushEventListener.java | 98 +++++++++++++ .../domain/friend/service/FriendService.java | 131 ++++++++---------- 4 files changed, 176 insertions(+), 75 deletions(-) create mode 100644 voicepocket/src/main/java/com/vp/voicepocket/domain/friend/event/FriendAcceptPushEvent.java create mode 100644 voicepocket/src/main/java/com/vp/voicepocket/domain/friend/event/FriendRequestPushEvent.java create mode 100644 voicepocket/src/main/java/com/vp/voicepocket/domain/friend/event/PushEventListener.java diff --git a/voicepocket/src/main/java/com/vp/voicepocket/domain/friend/event/FriendAcceptPushEvent.java b/voicepocket/src/main/java/com/vp/voicepocket/domain/friend/event/FriendAcceptPushEvent.java new file mode 100644 index 0000000..9b169af --- /dev/null +++ b/voicepocket/src/main/java/com/vp/voicepocket/domain/friend/event/FriendAcceptPushEvent.java @@ -0,0 +1,11 @@ +package com.vp.voicepocket.domain.friend.event; + +import com.vp.voicepocket.domain.friend.entity.Friend; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class FriendAcceptPushEvent { + private Friend friend; +} diff --git a/voicepocket/src/main/java/com/vp/voicepocket/domain/friend/event/FriendRequestPushEvent.java b/voicepocket/src/main/java/com/vp/voicepocket/domain/friend/event/FriendRequestPushEvent.java new file mode 100644 index 0000000..f42877e --- /dev/null +++ b/voicepocket/src/main/java/com/vp/voicepocket/domain/friend/event/FriendRequestPushEvent.java @@ -0,0 +1,11 @@ +package com.vp.voicepocket.domain.friend.event; + +import com.vp.voicepocket.domain.friend.entity.Friend; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class FriendRequestPushEvent { + private Friend friend; +} diff --git a/voicepocket/src/main/java/com/vp/voicepocket/domain/friend/event/PushEventListener.java b/voicepocket/src/main/java/com/vp/voicepocket/domain/friend/event/PushEventListener.java new file mode 100644 index 0000000..ad7faef --- /dev/null +++ b/voicepocket/src/main/java/com/vp/voicepocket/domain/friend/event/PushEventListener.java @@ -0,0 +1,98 @@ +package com.vp.voicepocket.domain.friend.event; + +import com.google.firebase.messaging.FirebaseMessaging; +import com.google.firebase.messaging.FirebaseMessagingException; +import com.google.firebase.messaging.Message; +import com.google.firebase.messaging.Notification; +import com.vp.voicepocket.domain.firebase.entity.FCMUserToken; +import com.vp.voicepocket.domain.firebase.exception.CFCMTokenNotFoundException; +import com.vp.voicepocket.domain.firebase.repository.FCMRepository; +import com.vp.voicepocket.domain.user.entity.User; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.event.TransactionPhase; +import org.springframework.transaction.event.TransactionalEventListener; + +import java.util.HashMap; + +@Slf4j +@Component +@RequiredArgsConstructor +public class PushEventListener { + private final FirebaseMessaging firebaseMessaging; + private final FCMRepository fcmRepository; + + @Async + @Transactional(propagation = Propagation.REQUIRES_NEW) + @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) + public void sendFriendRequestPushMessage(FriendRequestPushEvent friendRequestPushEvent) { + User toUser = friendRequestPushEvent.getFriend().getRequest_to(); + User fromUser = friendRequestPushEvent.getFriend().getRequest_from(); + + FCMUserToken fcmEntity = fcmRepository.findByUserId(toUser) + .orElseThrow(CFCMTokenNotFoundException::new); + String fcmToken = fcmEntity.getFireBaseToken(); + + try { + Message message = getFriendRequestPushMessage(fromUser.getName(), fcmToken); + firebaseMessaging.send(message); + } catch (FirebaseMessagingException e) { + log.error("PUSH NOTIFICATION ERROR: {}", e.getMessage()); + } + } + + @Async + @Transactional(propagation = Propagation.REQUIRES_NEW) + @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) + public void sendFriendAcceptPushMessage(FriendAcceptPushEvent friendAcceptPushEvent) { + User toUser = friendAcceptPushEvent.getFriend().getRequest_to(); + User fromUser = friendAcceptPushEvent.getFriend().getRequest_from(); + + FCMUserToken fcmEntity = fcmRepository.findByUserId(fromUser) + .orElseThrow(CFCMTokenNotFoundException::new); + String fcmToken = fcmEntity.getFireBaseToken(); + + try { + Message message = getFriendAcceptPushMessage(toUser.getName(), fcmToken); + firebaseMessaging.send(message); + } catch (FirebaseMessagingException e) { + log.error("PUSH NOTIFICATION ERROR: {}", e.getMessage()); + } + } + + private Message getFriendRequestPushMessage(String fromUserName, String fcmToken) { + Notification notification = Notification.builder() + .setTitle("Friend Request") + .setBody(fromUserName + " request Friend to you!") + .build(); + + HashMap data = new HashMap<>(); + data.put("ID", "1"); + + return Message.builder() + .setToken(fcmToken) + .setNotification(notification) + .putAllData(data) + .build(); + } + + private Message getFriendAcceptPushMessage(String toUserName, String fcmToken) { + Notification notification = Notification.builder() + .setTitle("Friend Accept") + .setBody(toUserName + " Accept your Friend Request!") + .build(); + + HashMap data = new HashMap<>(); + data.put("ID", "2"); + + return Message.builder() + .setToken(fcmToken) + .setNotification(notification) + .putAllData(data) + .build(); + } +} diff --git a/voicepocket/src/main/java/com/vp/voicepocket/domain/friend/service/FriendService.java b/voicepocket/src/main/java/com/vp/voicepocket/domain/friend/service/FriendService.java index f61b98b..ab8ee26 100644 --- a/voicepocket/src/main/java/com/vp/voicepocket/domain/friend/service/FriendService.java +++ b/voicepocket/src/main/java/com/vp/voicepocket/domain/friend/service/FriendService.java @@ -1,14 +1,11 @@ package com.vp.voicepocket.domain.friend.service; -import com.vp.voicepocket.domain.firebase.dto.FCMNotificationRequestDto; -import com.vp.voicepocket.domain.firebase.entity.FCMUserToken; -import com.vp.voicepocket.domain.firebase.exception.CFCMTokenNotFoundException; -import com.vp.voicepocket.domain.firebase.repository.FCMRepository; -import com.vp.voicepocket.domain.firebase.service.FCMNotificationService; import com.vp.voicepocket.domain.friend.dto.request.FriendRequestDto; import com.vp.voicepocket.domain.friend.dto.response.FriendResponseDto; import com.vp.voicepocket.domain.friend.entity.Friend; import com.vp.voicepocket.domain.friend.entity.Status; +import com.vp.voicepocket.domain.friend.event.FriendAcceptPushEvent; +import com.vp.voicepocket.domain.friend.event.FriendRequestPushEvent; import com.vp.voicepocket.domain.friend.exception.CFriendRequestNotExistException; import com.vp.voicepocket.domain.friend.exception.CFriendRequestOnGoingException; import com.vp.voicepocket.domain.friend.repository.FriendRepository; @@ -19,11 +16,11 @@ import com.vp.voicepocket.domain.user.exception.CUserNotFoundException; import com.vp.voicepocket.domain.user.repository.UserRepository; import lombok.RequiredArgsConstructor; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.security.core.Authentication; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; @@ -31,46 +28,31 @@ @RequiredArgsConstructor public class FriendService { private final UserRepository userRepository; - private final FCMRepository fcmRepository; private final FriendRepository friendRepository; - private final FCMNotificationService fcmNotificationService; + private final ApplicationEventPublisher eventPublisher; private final JwtProvider jwtProvider; + @Transactional public FriendResponseDto requestFriend(FriendRequestDto friendRequestDto, String accessToken) { - Authentication authentication= getAuthByAccessToken(accessToken); + Authentication authentication = getAuthByAccessToken(accessToken); - User to_user = - userRepository.findByEmail(friendRequestDto.getEmail()) - .orElseThrow(CUserNotFoundException::new); + User to_user = userRepository.findByEmail(friendRequestDto.getEmail()) + .orElseThrow(CUserNotFoundException::new); - User from_user = - userRepository.findById(Long.parseLong(authentication.getName())) - .orElseThrow(CUserNotFoundException::new); + User from_user = userRepository.findById(Long.parseLong(authentication.getName())) + .orElseThrow(CUserNotFoundException::new); if (friendRepository.findByRequest(from_user, to_user, Status.ONGOING).isPresent() || - friendRepository.findByRequest(from_user, to_user, Status.ACCEPT).isPresent()) { + friendRepository.findByRequest(from_user, to_user, Status.ACCEPT).isPresent()) { throw new CFriendRequestOnGoingException(); } - Friend friend = friendRequestDto.toEntity(from_user, to_user, Status.ONGOING); - - HashMap data = new HashMap<>(); - data.put("ID", "1"); - - FCMUserToken fcmEntity = fcmRepository.findByUserId(to_user) - .orElseThrow(CFCMTokenNotFoundException::new); - String fcmToken = fcmEntity.getFireBaseToken(); - - FCMNotificationRequestDto fcmNotificationRequestDto = FCMNotificationRequestDto.builder() - .firebaseToken(fcmToken) - .title("Friend Request") - .body(from_user.getName() + " request Friend to you!") - .build(); + Friend friendRequest = friendRequestDto.toEntity(from_user, to_user, Status.ONGOING); - fcmNotificationService.sendNotificationWithData(fcmNotificationRequestDto, data); + eventPublisher.publishEvent(new FriendRequestPushEvent(friendRequest)); - return mapFriendEntityToFriendResponseDTO(friendRepository.save(friend)); + return mapFriendEntityToFriendResponseDTO(friendRepository.save(friendRequest)); } private Authentication getAuthByAccessToken(String accessToken) { @@ -83,73 +65,72 @@ private Authentication getAuthByAccessToken(String accessToken) { return jwtProvider.getAuthentication(accessToken); } - private FriendResponseDto mapFriendEntityToFriendResponseDTO(Friend friend){ + private FriendResponseDto mapFriendEntityToFriendResponseDTO(Friend friend) { return FriendResponseDto.builder() - .id(friend.getId()) - .request_from(new UserResponseDto(friend.getRequest_from())) - .request_to(new UserResponseDto(friend.getRequest_to())) - .status(friend.getStatus()) - .build(); + .id(friend.getId()) + .request_from(new UserResponseDto(friend.getRequest_from())) + .request_to(new UserResponseDto(friend.getRequest_to())) + .status(friend.getStatus()) + .build(); } @Transactional public List checkRequest(String accessToken) { - Authentication authentication= getAuthByAccessToken(accessToken); - User to_user = userRepository.findById(Long.parseLong(authentication.getName())).orElseThrow(CUserNotFoundException::new); + Authentication authentication = getAuthByAccessToken(accessToken); + + User to_user = userRepository.findById(Long.parseLong(authentication.getName())) + .orElseThrow(CUserNotFoundException::new); + return friendRepository.findByToUser(to_user, Status.ONGOING) // 없을 때 공백 리스트를 반환하기 - .stream() - .map(this::mapFriendEntityToFriendResponseDTO) - .collect(Collectors.toList()); + .stream() + .map(this::mapFriendEntityToFriendResponseDTO) + .collect(Collectors.toList()); } @Transactional public List checkResponse(String accessToken) { - Authentication authentication= getAuthByAccessToken(accessToken); - User from_user = userRepository.findById(Long.parseLong(authentication.getName())).orElseThrow(CUserNotFoundException::new); + Authentication authentication = getAuthByAccessToken(accessToken); + + User from_user = userRepository.findById(Long.parseLong(authentication.getName())) + .orElseThrow(CUserNotFoundException::new); + return friendRepository.findByFromUser(from_user, Status.ACCEPT) // 없을 때 공백 리스트를 반환하기 - .stream() - .map(this::mapFriendEntityToFriendResponseDTO) - .collect(Collectors.toList()); + .stream() + .map(this::mapFriendEntityToFriendResponseDTO) + .collect(Collectors.toList()); } @Transactional - public void update(FriendRequestDto friendRequestDto, String accessToken, Status status){ - Authentication authentication= getAuthByAccessToken(accessToken); + public void update(FriendRequestDto friendRequestDto, String accessToken, Status status) { + Authentication authentication = getAuthByAccessToken(accessToken); User from_user = userRepository.findByEmail(friendRequestDto.getEmail()) - .orElseThrow(CUserNotFoundException::new); + .orElseThrow(CUserNotFoundException::new); User to_user = userRepository.findById(Long.parseLong(authentication.getName())) - .orElseThrow(CUserNotFoundException::new); - - Friend modifiedFriend = friendRepository.findByRequest(from_user, to_user, Status.ONGOING) - .orElseThrow(CFriendRequestNotExistException::new); - modifiedFriend.updateStatus(status); - - if(status.equals(Status.ACCEPT)){ - HashMap data = new HashMap<>(); - data.put("ID", "2"); - - FCMUserToken fcmEntity = fcmRepository.findByUserId(from_user) - .orElseThrow(CFCMTokenNotFoundException::new); - String fcmToken = fcmEntity.getFireBaseToken(); + .orElseThrow(CUserNotFoundException::new); - FCMNotificationRequestDto fcmNotificationRequestDto = FCMNotificationRequestDto.builder() - .firebaseToken(fcmToken) - .title("Friend Accept") - .body(to_user.getName() + " Accept your Friend Request!") - .build(); + Friend friendRequest = friendRepository.findByRequest(from_user, to_user, Status.ONGOING) + .orElseThrow(CFriendRequestNotExistException::new); + friendRequest.updateStatus(status); - fcmNotificationService.sendNotificationWithData(fcmNotificationRequestDto, data); + if (status.equals(Status.ACCEPT)) { + eventPublisher.publishEvent(new FriendAcceptPushEvent(friendRequest)); } } @Transactional - public void delete(FriendRequestDto friendRequestDto, String accessToken, Status status){ - Authentication authentication= getAuthByAccessToken(accessToken); - User from_user = userRepository.findById(Long.parseLong(authentication.getName())).orElseThrow(CUserNotFoundException::new); - User to_user = userRepository.findByEmail(friendRequestDto.getEmail()).orElseThrow(CUserNotFoundException::new); - Friend friend = friendRepository.findByRequest(from_user, to_user, status).orElseThrow(CFriendRequestNotExistException::new); + public void delete(FriendRequestDto friendRequestDto, String accessToken, Status status) { + Authentication authentication = getAuthByAccessToken(accessToken); + + User from_user = userRepository.findById(Long.parseLong(authentication.getName())) + .orElseThrow(CUserNotFoundException::new); + User to_user = userRepository.findByEmail(friendRequestDto.getEmail()) + .orElseThrow(CUserNotFoundException::new); + + Friend friend = friendRepository.findByRequest(from_user, to_user, status) + .orElseThrow(CFriendRequestNotExistException::new); + friendRepository.delete(friend); } }