Skip to content

Commit

Permalink
Refactor/#35 팔로우 기능의 메인 로직과 푸시 알림 로직을 event 적용 및 비동기 처리 (#36)
Browse files Browse the repository at this point in the history
* feat: 팔로우 신청 및 수락용 event 추가

* feat: push 알림 이벤트용 리스너 추가

* refactor: 푸시 알림 이벤트를 발행하도록 수정
  • Loading branch information
hi-june authored Feb 3, 2024
1 parent f942ef9 commit cf0532b
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 75 deletions.
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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<String, String> 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<String, String> data = new HashMap<>();
data.put("ID", "2");

return Message.builder()
.setToken(fcmToken)
.setNotification(notification)
.putAllData(data)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -19,58 +16,43 @@
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;

@Service
@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<String, String> 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) {
Expand All @@ -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<FriendResponseDto> 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<FriendResponseDto> 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<String, String> 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);
}
}

0 comments on commit cf0532b

Please sign in to comment.