From ab9fd41ec858e7411356a01cb04efa1c0a4b2db9 Mon Sep 17 00:00:00 2001 From: minsu20 Date: Sat, 27 Jan 2024 23:53:00 +0900 Subject: [PATCH 1/9] =?UTF-8?q?MNG-01=20fix:=20=EC=9C=A0=EB=8B=88=ED=81=AC?= =?UTF-8?q?=20=EB=B3=B5=ED=95=A9=20=ED=82=A4=EB=A1=9C=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=20=ED=9B=84=20=EB=9D=BD=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../boardRead/domain/repository/BoardReadRepository.java | 1 - .../teamMember/domain/repository/TeamMemberRepository.java | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/com/moing/backend/domain/boardRead/domain/repository/BoardReadRepository.java b/src/main/java/com/moing/backend/domain/boardRead/domain/repository/BoardReadRepository.java index 2be1ae98..81724604 100644 --- a/src/main/java/com/moing/backend/domain/boardRead/domain/repository/BoardReadRepository.java +++ b/src/main/java/com/moing/backend/domain/boardRead/domain/repository/BoardReadRepository.java @@ -13,6 +13,5 @@ public interface BoardReadRepository extends JpaRepository { - @Lock(LockModeType.PESSIMISTIC_WRITE) List findBoardReadByBoardAndMemberAndTeam(Board board, Member member, Team team); } diff --git a/src/main/java/com/moing/backend/domain/teamMember/domain/repository/TeamMemberRepository.java b/src/main/java/com/moing/backend/domain/teamMember/domain/repository/TeamMemberRepository.java index 503cd5bb..b7ab7bbe 100644 --- a/src/main/java/com/moing/backend/domain/teamMember/domain/repository/TeamMemberRepository.java +++ b/src/main/java/com/moing/backend/domain/teamMember/domain/repository/TeamMemberRepository.java @@ -4,16 +4,14 @@ import com.moing.backend.domain.team.domain.entity.Team; import com.moing.backend.domain.teamMember.domain.entity.TeamMember; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Lock; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; -import javax.persistence.LockModeType; import javax.swing.text.html.Option; import java.util.Optional; public interface TeamMemberRepository extends JpaRepository, TeamMemberCustomRepository{ - @Lock(LockModeType.PESSIMISTIC_WRITE) Optional findTeamMemberByTeamAndMember(Team team, Member member); + } From d4b01f52da60e40638f746484cbbd044cfa04e38 Mon Sep 17 00:00:00 2001 From: minsu20 Date: Sun, 28 Jan 2024 03:52:01 +0900 Subject: [PATCH 2/9] =?UTF-8?q?MNG-01=20fix:=20=ED=83=88=ED=87=B4=20?= =?UTF-8?q?=EC=A4=91=EB=B3=B5=20=EC=95=88=EB=90=98=EA=B2=8C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../team/application/service/DisbandTeamUseCase.java | 2 +- .../team/application/service/WithdrawTeamUseCase.java | 2 +- .../teamMember/domain/service/TeamMemberGetService.java | 9 ++++++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/moing/backend/domain/team/application/service/DisbandTeamUseCase.java b/src/main/java/com/moing/backend/domain/team/application/service/DisbandTeamUseCase.java index 5e5f29df..cf6eb651 100644 --- a/src/main/java/com/moing/backend/domain/team/application/service/DisbandTeamUseCase.java +++ b/src/main/java/com/moing/backend/domain/team/application/service/DisbandTeamUseCase.java @@ -28,7 +28,7 @@ public DeleteTeamResponse disbandTeam(String socialId, Long teamId) { checkLeaderUseCase.validateTeamLeader(member, team); team.deleteTeam(); if (team.getNumOfMember() == 1) { // 1명인 경우 3일 유예기간 없음 - TeamMember teamMember = teamMemberGetService.getTeamMember(member, team); + TeamMember teamMember = teamMemberGetService.getTeamMemberNotDeleted(member, team); teamMember.deleteMember(team); } return new DeleteTeamResponse(teamId); diff --git a/src/main/java/com/moing/backend/domain/team/application/service/WithdrawTeamUseCase.java b/src/main/java/com/moing/backend/domain/team/application/service/WithdrawTeamUseCase.java index e4e007eb..4e69e4d7 100644 --- a/src/main/java/com/moing/backend/domain/team/application/service/WithdrawTeamUseCase.java +++ b/src/main/java/com/moing/backend/domain/team/application/service/WithdrawTeamUseCase.java @@ -24,7 +24,7 @@ public class WithdrawTeamUseCase { public DeleteTeamResponse withdrawTeam(String socialId, Long teamId) { Member member = memberGetService.getMemberBySocialId(socialId); Team team = teamGetService.getTeamByTeamId(teamId); - TeamMember teamMember = teamMemberGetService.getTeamMember(member, team); + TeamMember teamMember = teamMemberGetService.getTeamMemberNotDeleted(member, team); teamMember.deleteMember(team); return new DeleteTeamResponse(teamId); } diff --git a/src/main/java/com/moing/backend/domain/teamMember/domain/service/TeamMemberGetService.java b/src/main/java/com/moing/backend/domain/teamMember/domain/service/TeamMemberGetService.java index 00d065a3..1e0a64cb 100644 --- a/src/main/java/com/moing/backend/domain/teamMember/domain/service/TeamMemberGetService.java +++ b/src/main/java/com/moing/backend/domain/teamMember/domain/service/TeamMemberGetService.java @@ -24,9 +24,16 @@ public List getTeamMemberIds(Long teamId){ } public TeamMember getTeamMember(Member member, Team team){ - return teamMemberRepository.findTeamMemberByTeamAndMember(team, member).orElseThrow(()-> new NotFoundByTeamIdException()); + return teamMemberRepository.findTeamMemberByTeamAndMember(team, member).orElseThrow(NotFoundByTeamIdException::new); } + public TeamMember getTeamMemberNotDeleted(Member member, Team team) { + return teamMemberRepository.findTeamMemberByTeamAndMember(team, member) + .filter(teamMember -> !teamMember.isDeleted()) + .orElseThrow(NotFoundByTeamIdException::new); + } + + public Optional> getFcmTokensExceptMe(Long teamId, Long memberId) { return teamMemberRepository.findFcmTokensByTeamIdAndMemberId(teamId, memberId); } From 19c5997a9b77a1f480e029008ff8270edb3a482d Mon Sep 17 00:00:00 2001 From: minsu20 Date: Sun, 28 Jan 2024 04:18:55 +0900 Subject: [PATCH 3/9] =?UTF-8?q?MNG-01=20refactor=20:=20mapper=20static=20?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/apple/AppleSignInUseCase.java | 2 +- .../service/google/GoogleSignInUseCase.java | 3 +-- .../service/kakao/KakaoSignInUseCase.java | 3 +-- .../service/BlockCreateUseCase.java | 3 --- .../service/BlockDeleteUseCase.java | 3 --- .../application/service/BlockReadUseCase.java | 16 ++++---------- .../board/application/mapper/BoardMapper.java | 6 +++--- .../service/CreateBoardUseCase.java | 3 +-- .../application/service/GetBoardUseCase.java | 3 +-- .../mapper/BoardCommentMapper.java | 2 +- .../service/CreateBoardCommentUseCase.java | 3 +-- .../application/mapper/BoardReadMapper.java | 2 +- .../service/CreateBoardReadUseCase.java | 3 +-- .../mapper/AlarmHistoryMapper.java | 4 ++-- .../service/SaveMultiAlarmHistoryUseCase.java | 3 +-- .../SaveSingleAlarmHistoryUseCase.java | 3 +-- .../application/mapper/MemberMapper.java | 21 ++++++++----------- .../application/mapper/MyPageMapper.java | 2 +- .../application/service/GetMyPageUseCase.java | 5 ++--- .../application/service/GetTeamUseCase.java | 5 ++--- .../service/ReviewTeamUseCase.java | 3 +-- 21 files changed, 35 insertions(+), 63 deletions(-) diff --git a/src/main/java/com/moing/backend/domain/auth/application/service/apple/AppleSignInUseCase.java b/src/main/java/com/moing/backend/domain/auth/application/service/apple/AppleSignInUseCase.java index 6f498fb6..323ebd51 100644 --- a/src/main/java/com/moing/backend/domain/auth/application/service/apple/AppleSignInUseCase.java +++ b/src/main/java/com/moing/backend/domain/auth/application/service/apple/AppleSignInUseCase.java @@ -22,6 +22,6 @@ public Member getUserData(String identityToken) { String socialId = oidcTokenJws.getBody().getSubject(); String email = (String) oidcTokenJws.getBody().get("email"); - return memberMapper.createAppleMember(socialId, email); + return MemberMapper.createAppleMember(socialId, email); } } diff --git a/src/main/java/com/moing/backend/domain/auth/application/service/google/GoogleSignInUseCase.java b/src/main/java/com/moing/backend/domain/auth/application/service/google/GoogleSignInUseCase.java index 5873460a..69993fd4 100644 --- a/src/main/java/com/moing/backend/domain/auth/application/service/google/GoogleSignInUseCase.java +++ b/src/main/java/com/moing/backend/domain/auth/application/service/google/GoogleSignInUseCase.java @@ -16,7 +16,6 @@ @RequiredArgsConstructor public class GoogleSignInUseCase implements SignInProvider { - private final MemberMapper memberMapper; private final WebClient webClient; private final GoogleTokenUseCase googleTokenUseCase; @@ -32,7 +31,7 @@ public Member getUserData(String accessToken) { if (googleUserResponse != null) { googleTokenUseCase.verifyAccessToken(googleUserResponse.getAud()); googleUserResponse.adaptResponse(); - return memberMapper.createGoogleMember(googleUserResponse); + return MemberMapper.createGoogleMember(googleUserResponse); } throw new TokenInvalidException(); } diff --git a/src/main/java/com/moing/backend/domain/auth/application/service/kakao/KakaoSignInUseCase.java b/src/main/java/com/moing/backend/domain/auth/application/service/kakao/KakaoSignInUseCase.java index 9fbf06e5..7e955df4 100644 --- a/src/main/java/com/moing/backend/domain/auth/application/service/kakao/KakaoSignInUseCase.java +++ b/src/main/java/com/moing/backend/domain/auth/application/service/kakao/KakaoSignInUseCase.java @@ -17,7 +17,6 @@ public class KakaoSignInUseCase implements SignInProvider { private final WebClient webClient; - private final MemberMapper memberMapper; private final KakaoTokenUseCase kakaoTokenUseCase; public Member getUserData(String accessToken) { @@ -35,6 +34,6 @@ public Member getUserData(String accessToken) { .block(); kakaoUserResponse.adaptResponse(); - return memberMapper.createKakaoMember(kakaoUserResponse); + return MemberMapper.createKakaoMember(kakaoUserResponse); } } diff --git a/src/main/java/com/moing/backend/domain/block/application/service/BlockCreateUseCase.java b/src/main/java/com/moing/backend/domain/block/application/service/BlockCreateUseCase.java index 2094c929..db8e6b25 100644 --- a/src/main/java/com/moing/backend/domain/block/application/service/BlockCreateUseCase.java +++ b/src/main/java/com/moing/backend/domain/block/application/service/BlockCreateUseCase.java @@ -17,9 +17,6 @@ public class BlockCreateUseCase { private final MemberGetService memberGetService; - private final BoardGetService boardGetService; - private final MissionArchiveQueryService missionArchiveQueryService; - private final BlockSaveService blockSaveService; diff --git a/src/main/java/com/moing/backend/domain/block/application/service/BlockDeleteUseCase.java b/src/main/java/com/moing/backend/domain/block/application/service/BlockDeleteUseCase.java index f262c244..1101ccc8 100644 --- a/src/main/java/com/moing/backend/domain/block/application/service/BlockDeleteUseCase.java +++ b/src/main/java/com/moing/backend/domain/block/application/service/BlockDeleteUseCase.java @@ -17,9 +17,6 @@ public class BlockDeleteUseCase { private final MemberGetService memberGetService; - private final BoardGetService boardGetService; - private final MissionArchiveQueryService missionArchiveQueryService; - private final BlockDeleteService blockDeleteService; diff --git a/src/main/java/com/moing/backend/domain/block/application/service/BlockReadUseCase.java b/src/main/java/com/moing/backend/domain/block/application/service/BlockReadUseCase.java index c66922dd..6f108b08 100644 --- a/src/main/java/com/moing/backend/domain/block/application/service/BlockReadUseCase.java +++ b/src/main/java/com/moing/backend/domain/block/application/service/BlockReadUseCase.java @@ -1,12 +1,7 @@ package com.moing.backend.domain.block.application.service; -import com.moing.backend.domain.block.application.mapper.BlockMapper; -import com.moing.backend.domain.block.domain.service.BlockDeleteService; import com.moing.backend.domain.block.domain.service.BlockQueryService; -import com.moing.backend.domain.block.domain.service.BlockSaveService; -import com.moing.backend.domain.board.domain.service.BoardGetService; import com.moing.backend.domain.member.domain.service.MemberGetService; -import com.moing.backend.domain.missionArchive.domain.service.MissionArchiveQueryService; import com.moing.backend.domain.report.application.dto.BlockMemberRes; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -18,9 +13,6 @@ public class BlockReadUseCase { private final MemberGetService memberGetService; - private final BoardGetService boardGetService; - private final MissionArchiveQueryService missionArchiveQueryService; - private final BlockQueryService blockQueryService; /** @@ -31,10 +23,10 @@ public List getMyBlockList(String socialId) { return blockQueryService.getBlockLists(memberId); } - public List getMyBlockInfoList(String socialId) { - Long memberId = memberGetService.getMemberBySocialId(socialId).getMemberId(); + public List getMyBlockInfoList(String socialId) { + Long memberId = memberGetService.getMemberBySocialId(socialId).getMemberId(); - return blockQueryService.getBlockInfoLists(memberId); - } + return blockQueryService.getBlockInfoLists(memberId); + } } diff --git a/src/main/java/com/moing/backend/domain/board/application/mapper/BoardMapper.java b/src/main/java/com/moing/backend/domain/board/application/mapper/BoardMapper.java index 9d98f4c3..eed680d5 100644 --- a/src/main/java/com/moing/backend/domain/board/application/mapper/BoardMapper.java +++ b/src/main/java/com/moing/backend/domain/board/application/mapper/BoardMapper.java @@ -16,7 +16,7 @@ @RequiredArgsConstructor public class BoardMapper { - public Board toBoard(TeamMember teamMember, Team team, CreateBoardRequest createBoardRequest, boolean isLeader) { + public static Board toBoard(TeamMember teamMember, Team team, CreateBoardRequest createBoardRequest, boolean isLeader) { Board board = Board.builder() .title(createBoardRequest.getTitle()) .content(createBoardRequest.getContent()) @@ -31,7 +31,7 @@ public Board toBoard(TeamMember teamMember, Team team, CreateBoardRequest create return board; } - public GetBoardDetailResponse toBoardDetail(Board board, boolean isWriter, boolean writerIsDeleted) { + public static GetBoardDetailResponse toBoardDetail(Board board, boolean isWriter, boolean writerIsDeleted) { String nickName = writerIsDeleted ? "(알 수 없음)" : board.getTeamMember().getMember().getNickName(); String writerProfileImage = writerIsDeleted ? null : board.getTeamMember().getMember().getProfileImage(); Long writerId = writerIsDeleted ? 0L : board.getTeamMember().getMember().getMemberId(); @@ -49,7 +49,7 @@ public GetBoardDetailResponse toBoardDetail(Board board, boolean isWriter, boole .build(); } - public String getFormattedDate(LocalDateTime localDateTime) { + public static String getFormattedDate(LocalDateTime localDateTime) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm"); return localDateTime.format(formatter); } diff --git a/src/main/java/com/moing/backend/domain/board/application/service/CreateBoardUseCase.java b/src/main/java/com/moing/backend/domain/board/application/service/CreateBoardUseCase.java index 35ec9102..c7b69d31 100644 --- a/src/main/java/com/moing/backend/domain/board/application/service/CreateBoardUseCase.java +++ b/src/main/java/com/moing/backend/domain/board/application/service/CreateBoardUseCase.java @@ -27,7 +27,6 @@ public class CreateBoardUseCase { private final BoardSaveService boardSaveService; private final CheckLeaderUseCase checkLeaderUseCase; - private final BoardMapper boardMapper; private final CreateBoardReadUseCase createBoardReadUseCase; private final BaseService baseService; private final SendBoardAlarmUseCase sendBoardAlarmUseCase; @@ -39,7 +38,7 @@ public CreateBoardResponse createBoard(String socialId, Long teamId, CreateBoard //1, 게시글 생성, 저장 BaseServiceResponse data=baseService.getCommonData(socialId, teamId); boolean isLeader = checkLeaderUseCase.isTeamLeader(data.getMember(), data.getTeam()); //작성자 리더 여부 - Board board=boardSaveService.saveBoard(boardMapper.toBoard(data.getTeamMember(), data.getTeam(), createBoardRequest, isLeader)); + Board board=boardSaveService.saveBoard(BoardMapper.toBoard(data.getTeamMember(), data.getTeam(), createBoardRequest, isLeader)); //2. 읽음 처리 - 생성한 사람은 무조건 읽음 createBoardReadUseCase.createBoardRead(data.getTeam(), data.getMember(), board); diff --git a/src/main/java/com/moing/backend/domain/board/application/service/GetBoardUseCase.java b/src/main/java/com/moing/backend/domain/board/application/service/GetBoardUseCase.java index ae8b14ce..5ac5e4d9 100644 --- a/src/main/java/com/moing/backend/domain/board/application/service/GetBoardUseCase.java +++ b/src/main/java/com/moing/backend/domain/board/application/service/GetBoardUseCase.java @@ -19,7 +19,6 @@ public class GetBoardUseCase { private final BaseBoardService baseBoardService; - private final BoardMapper boardMapper; private final MemberGetService memberGetService; private final CreateBoardReadUseCase createBoardReadUseCase; private final BoardGetService boardGetService; @@ -34,7 +33,7 @@ public GetBoardDetailResponse getBoardDetail(String socialId, Long teamId, Long BaseBoardServiceResponse data = baseBoardService.getCommonData(socialId, teamId, boardId); // 2. 읽음 처리 createBoardReadUseCase.createBoardRead(data.getTeam(), data.getMember(), data.getBoard()); - return boardMapper.toBoardDetail(data.getBoard(), data.getTeamMember() == data.getBoard().getTeamMember(), data.getBoard().getTeamMember().isDeleted()); + return BoardMapper.toBoardDetail(data.getBoard(), data.getTeamMember() == data.getBoard().getTeamMember(), data.getBoard().getTeamMember().isDeleted()); } /** diff --git a/src/main/java/com/moing/backend/domain/boardComment/application/mapper/BoardCommentMapper.java b/src/main/java/com/moing/backend/domain/boardComment/application/mapper/BoardCommentMapper.java index 8e0fe2e2..e2311e2a 100644 --- a/src/main/java/com/moing/backend/domain/boardComment/application/mapper/BoardCommentMapper.java +++ b/src/main/java/com/moing/backend/domain/boardComment/application/mapper/BoardCommentMapper.java @@ -10,7 +10,7 @@ @Component @RequiredArgsConstructor public class BoardCommentMapper { - public BoardComment toBoardComment(TeamMember teamMember, Board board, CreateBoardCommentRequest createBoardCommentRequest, boolean isLeader) { + public static BoardComment toBoardComment(TeamMember teamMember, Board board, CreateBoardCommentRequest createBoardCommentRequest, boolean isLeader) { BoardComment boardComment= BoardComment.builder() .content(createBoardCommentRequest.getContent()) .isLeader(isLeader) diff --git a/src/main/java/com/moing/backend/domain/boardComment/application/service/CreateBoardCommentUseCase.java b/src/main/java/com/moing/backend/domain/boardComment/application/service/CreateBoardCommentUseCase.java index f51b5172..39b1f4ea 100644 --- a/src/main/java/com/moing/backend/domain/boardComment/application/service/CreateBoardCommentUseCase.java +++ b/src/main/java/com/moing/backend/domain/boardComment/application/service/CreateBoardCommentUseCase.java @@ -19,7 +19,6 @@ public class CreateBoardCommentUseCase { private final BoardCommentSaveService boardCommentSaveService; - private final BoardCommentMapper boardCommentMapper; private final BaseBoardService baseBoardService; private final CheckLeaderUseCase checkLeaderUseCase; @@ -30,7 +29,7 @@ public CreateBoardCommentResponse createBoardComment(String socialId, Long teamI // 1. 게시글 댓글 생성 BaseBoardServiceResponse data = baseBoardService.getCommonData(socialId, teamId, boardId); boolean isLeader = checkLeaderUseCase.isTeamLeader(data.getMember(), data.getTeam()); - BoardComment boardComment = boardCommentSaveService.saveBoardComment(boardCommentMapper.toBoardComment(data.getTeamMember(), data.getBoard(), createBoardCommentRequest, isLeader)); + BoardComment boardComment = boardCommentSaveService.saveBoardComment(BoardCommentMapper.toBoardComment(data.getTeamMember(), data.getBoard(), createBoardCommentRequest, isLeader)); // 2. 게시글 댓글 개수 증가 data.getBoard().incrComNum(); return new CreateBoardCommentResponse(boardComment.getBoardCommentId()); diff --git a/src/main/java/com/moing/backend/domain/boardRead/application/mapper/BoardReadMapper.java b/src/main/java/com/moing/backend/domain/boardRead/application/mapper/BoardReadMapper.java index 740e6b1a..9f58858c 100644 --- a/src/main/java/com/moing/backend/domain/boardRead/application/mapper/BoardReadMapper.java +++ b/src/main/java/com/moing/backend/domain/boardRead/application/mapper/BoardReadMapper.java @@ -8,7 +8,7 @@ @Component public class BoardReadMapper { - public BoardRead toBoardRead(Team team, Member member){ + public static BoardRead toBoardRead(Team team, Member member){ BoardRead boardRead=new BoardRead(); boardRead.updateTeam(team); boardRead.updateMember(member); diff --git a/src/main/java/com/moing/backend/domain/boardRead/application/service/CreateBoardReadUseCase.java b/src/main/java/com/moing/backend/domain/boardRead/application/service/CreateBoardReadUseCase.java index d1146dd9..efb39fc1 100644 --- a/src/main/java/com/moing/backend/domain/boardRead/application/service/CreateBoardReadUseCase.java +++ b/src/main/java/com/moing/backend/domain/boardRead/application/service/CreateBoardReadUseCase.java @@ -16,11 +16,10 @@ @RequiredArgsConstructor public class CreateBoardReadUseCase { - private final BoardReadMapper boardReadMapper; private final BoardReadSaveService boardReadSaveService; public void createBoardRead(Team team, Member member, Board board){ - BoardRead boardRead = boardReadMapper.toBoardRead(team, member); + BoardRead boardRead = BoardReadMapper.toBoardRead(team, member); boardReadSaveService.saveBoardRead(board, boardRead); } } diff --git a/src/main/java/com/moing/backend/domain/history/application/mapper/AlarmHistoryMapper.java b/src/main/java/com/moing/backend/domain/history/application/mapper/AlarmHistoryMapper.java index e00f121e..e6c2c83d 100644 --- a/src/main/java/com/moing/backend/domain/history/application/mapper/AlarmHistoryMapper.java +++ b/src/main/java/com/moing/backend/domain/history/application/mapper/AlarmHistoryMapper.java @@ -16,7 +16,7 @@ @RequiredArgsConstructor public class AlarmHistoryMapper { - public AlarmHistory toAlarmHistory(AlarmType type, String path, String idInfo, Long receiverId, String title, String body, String name){ + public static AlarmHistory toAlarmHistory(AlarmType type, String path, String idInfo, Long receiverId, String title, String body, String name){ return AlarmHistory.builder() .type(type) .path(path) @@ -50,7 +50,7 @@ public static List getMemberIds(List memberIdAndTokens) .collect(Collectors.toList()); } - public List getAlarmHistories(String idInfo, List memberIds, String title, String body, String teamName, AlarmType alarmType, String path) { + public static List getAlarmHistories(String idInfo, List memberIds, String title, String body, String teamName, AlarmType alarmType, String path) { return memberIds.stream() .map(memberId -> toAlarmHistory(alarmType, path, idInfo, memberId, title, body, teamName)) .collect(Collectors.toList()); diff --git a/src/main/java/com/moing/backend/domain/history/application/service/SaveMultiAlarmHistoryUseCase.java b/src/main/java/com/moing/backend/domain/history/application/service/SaveMultiAlarmHistoryUseCase.java index 0831b3b8..ab386647 100644 --- a/src/main/java/com/moing/backend/domain/history/application/service/SaveMultiAlarmHistoryUseCase.java +++ b/src/main/java/com/moing/backend/domain/history/application/service/SaveMultiAlarmHistoryUseCase.java @@ -14,12 +14,11 @@ @RequiredArgsConstructor public class SaveMultiAlarmHistoryUseCase { - private final AlarmHistoryMapper alarmHistoryMapper; private final AlarmHistorySaveService alarmHistorySaveService; @Async public void saveAlarmHistories(List memberIds, String idInfo, String title, String body, String name, AlarmType alarmType, String path) { - List alarmHistories = alarmHistoryMapper.getAlarmHistories(idInfo, memberIds, title, body, name, alarmType, path); + List alarmHistories = AlarmHistoryMapper.getAlarmHistories(idInfo, memberIds, title, body, name, alarmType, path); alarmHistorySaveService.saveAlarmHistories(alarmHistories); } } diff --git a/src/main/java/com/moing/backend/domain/history/application/service/SaveSingleAlarmHistoryUseCase.java b/src/main/java/com/moing/backend/domain/history/application/service/SaveSingleAlarmHistoryUseCase.java index 61030af7..90f1a63d 100644 --- a/src/main/java/com/moing/backend/domain/history/application/service/SaveSingleAlarmHistoryUseCase.java +++ b/src/main/java/com/moing/backend/domain/history/application/service/SaveSingleAlarmHistoryUseCase.java @@ -12,12 +12,11 @@ @RequiredArgsConstructor public class SaveSingleAlarmHistoryUseCase { - private final AlarmHistoryMapper alarmHistoryMapper; private final AlarmHistorySaveService alarmHistorySaveService; @Async public void saveAlarmHistory(Long memberId, String idInfo, String title, String body, String name, AlarmType alarmType, String path) { - AlarmHistory alarmHistory = alarmHistoryMapper.toAlarmHistory(alarmType, path, idInfo, memberId, title, body, name); + AlarmHistory alarmHistory = AlarmHistoryMapper.toAlarmHistory(alarmType, path, idInfo, memberId, title, body, name); alarmHistorySaveService.saveAlarmHistory(alarmHistory); } } diff --git a/src/main/java/com/moing/backend/domain/member/application/mapper/MemberMapper.java b/src/main/java/com/moing/backend/domain/member/application/mapper/MemberMapper.java index 84ceea6e..8b20e694 100644 --- a/src/main/java/com/moing/backend/domain/member/application/mapper/MemberMapper.java +++ b/src/main/java/com/moing/backend/domain/member/application/mapper/MemberMapper.java @@ -11,39 +11,36 @@ @Component public class MemberMapper { - public Member createKakaoMember(KakaoUserResponse kakaoUserResponse) { - Member newMember = Member.builder() + public static Member createKakaoMember(KakaoUserResponse kakaoUserResponse) { + + return Member.builder() .socialId(SocialProvider.KAKAO + "@" + kakaoUserResponse.getId()) .provider(SocialProvider.KAKAO) .email(kakaoUserResponse.getKakaoAccount().getEmail()) .role(Role.USER) .registrationStatus(RegistrationStatus.UNCOMPLETED) .build(); - - return newMember; } - public Member createAppleMember(String socialId, String email) { - Member newMember = Member.builder() + public static Member createAppleMember(String socialId, String email) { + + return Member.builder() .socialId(SocialProvider.APPLE + "@" + socialId) .provider(SocialProvider.APPLE) .email(email) .role(Role.USER) .registrationStatus(RegistrationStatus.UNCOMPLETED) .build(); - - return newMember; } - public Member createGoogleMember(GoogleUserResponse googleUserResponse){ - Member newMember= Member.builder() + public static Member createGoogleMember(GoogleUserResponse googleUserResponse){ + + return Member.builder() .socialId(SocialProvider.GOOGLE + "@" + googleUserResponse.getSub()) .provider(SocialProvider.GOOGLE) .email(googleUserResponse.getEmail()) .role(Role.USER) .registrationStatus(RegistrationStatus.UNCOMPLETED) .build(); - - return newMember; } } diff --git a/src/main/java/com/moing/backend/domain/mypage/application/mapper/MyPageMapper.java b/src/main/java/com/moing/backend/domain/mypage/application/mapper/MyPageMapper.java index fd09f4ed..65fd7992 100644 --- a/src/main/java/com/moing/backend/domain/mypage/application/mapper/MyPageMapper.java +++ b/src/main/java/com/moing/backend/domain/mypage/application/mapper/MyPageMapper.java @@ -13,7 +13,7 @@ @RequiredArgsConstructor public class MyPageMapper { - public GetMyPageResponse toGetMyPageResponse(Member member, List categories, List blocks) { + public static GetMyPageResponse toGetMyPageResponse(Member member, List categories, List blocks) { return GetMyPageResponse.builder() .profileImage(member.getProfileImage()) .nickName(member.getNickName()) diff --git a/src/main/java/com/moing/backend/domain/mypage/application/service/GetMyPageUseCase.java b/src/main/java/com/moing/backend/domain/mypage/application/service/GetMyPageUseCase.java index 3e1db9b4..c86e9488 100644 --- a/src/main/java/com/moing/backend/domain/mypage/application/service/GetMyPageUseCase.java +++ b/src/main/java/com/moing/backend/domain/mypage/application/service/GetMyPageUseCase.java @@ -20,16 +20,15 @@ public class GetMyPageUseCase { private final MemberGetService memberGetService; private final TeamGetService teamGetService; - private final MyPageMapper myPageMapper; @Transactional(readOnly = true) public GetMyPageResponse getMyPageResponse(String socialId) { Member member = memberGetService.getMemberBySocialId(socialId); List getMyPageTeamBlocks = teamGetService.getMyPageTeamBlockByMemberId(member.getMemberId()); - return myPageMapper.toGetMyPageResponse(member, calculateCategory(getMyPageTeamBlocks), getMyPageTeamBlocks); + return MyPageMapper.toGetMyPageResponse(member, calculateCategory(getMyPageTeamBlocks), getMyPageTeamBlocks); } - private List calculateCategory(List getMyPageTeamBlocks) { + private static List calculateCategory(List getMyPageTeamBlocks) { return getMyPageTeamBlocks.stream() .map(GetMyPageTeamBlock::getCategory) .distinct() diff --git a/src/main/java/com/moing/backend/domain/team/application/service/GetTeamUseCase.java b/src/main/java/com/moing/backend/domain/team/application/service/GetTeamUseCase.java index d81edcba..7d950dc7 100644 --- a/src/main/java/com/moing/backend/domain/team/application/service/GetTeamUseCase.java +++ b/src/main/java/com/moing/backend/domain/team/application/service/GetTeamUseCase.java @@ -24,7 +24,6 @@ public class GetTeamUseCase { private final TeamGetService teamGetService; private final BoardGetService boardGetService; private final TeamMemberGetService teamMemberGetService; - private final TeamMapper teamMapper; public GetTeamResponse getTeam(String socialId) { Member member = memberGetService.getMemberBySocialId(socialId); @@ -36,12 +35,12 @@ public GetTeamDetailResponse getTeamDetailResponse(String socialId, Long teamId) Integer boardNum = boardGetService.getUnReadBoardNum(teamId, member.getMemberId()); List teamMemberInfoList = teamMemberGetService.getTeamMemberInfo(teamId); Team team = teamGetService.getTeamByTeamId(teamId); - return teamMapper.toTeamDetailResponse(member.getMemberId(), team, boardNum, teamMemberInfoList); + return TeamMapper.toTeamDetailResponse(member.getMemberId(), team, boardNum, teamMemberInfoList); } public GetCurrentStatusResponse getCurrentStatus(Long teamId) { Team team=teamGetService.getTeamByTeamId(teamId); - return teamMapper.toCurrentStatusResponse(team); + return TeamMapper.toCurrentStatusResponse(team); } public Page getNewTeam(String dateSort, Pageable pageable) { diff --git a/src/main/java/com/moing/backend/domain/team/application/service/ReviewTeamUseCase.java b/src/main/java/com/moing/backend/domain/team/application/service/ReviewTeamUseCase.java index 7176ca7a..47d85194 100644 --- a/src/main/java/com/moing/backend/domain/team/application/service/ReviewTeamUseCase.java +++ b/src/main/java/com/moing/backend/domain/team/application/service/ReviewTeamUseCase.java @@ -18,7 +18,6 @@ public class ReviewTeamUseCase { private final TeamGetService teamGetService; - private final TeamMapper teamMapper; private final MissionQueryService missionQueryService; private final CheckLeaderUseCase checkLeaderUseCase; private final MemberGetService memberGetService; @@ -27,6 +26,6 @@ public ReviewTeamResponse reviewTeam(String socialId, Long teamId){ Team team=teamGetService.getTeamByTeamId(teamId); Member member=memberGetService.getMemberBySocialId(socialId); boolean isLeader=checkLeaderUseCase.isTeamLeader(member, team); - return teamMapper.toReviewTeamResponse(missionQueryService.findMissionsCountByTeam(team.getTeamId()),team, isLeader, member.getNickName()); + return TeamMapper.toReviewTeamResponse(missionQueryService.findMissionsCountByTeam(team.getTeamId()),team, isLeader, member.getNickName()); } } From b15ff03ffe502907d5fc16d7afa713e2efa80242 Mon Sep 17 00:00:00 2001 From: minsu20 Date: Sun, 28 Jan 2024 04:20:25 +0900 Subject: [PATCH 4/9] =?UTF-8?q?MNG-01=20fix:=20=EC=86=8C=EB=AA=A8=EC=9E=84?= =?UTF-8?q?=20=EC=8A=B9=EC=9D=B8=20=EC=BD=94=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/ApproveTeamUseCase.java | 37 ------------ .../presentation/AdminTeamController.java | 60 ------------------- 2 files changed, 97 deletions(-) delete mode 100644 src/main/java/com/moing/backend/domain/team/application/service/ApproveTeamUseCase.java delete mode 100644 src/main/java/com/moing/backend/domain/team/presentation/AdminTeamController.java diff --git a/src/main/java/com/moing/backend/domain/team/application/service/ApproveTeamUseCase.java b/src/main/java/com/moing/backend/domain/team/application/service/ApproveTeamUseCase.java deleted file mode 100644 index 51b8a1db..00000000 --- a/src/main/java/com/moing/backend/domain/team/application/service/ApproveTeamUseCase.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.moing.backend.domain.team.application.service; - -import com.moing.backend.domain.history.domain.entity.AlarmType; -import com.moing.backend.domain.team.application.dto.response.GetLeaderInfoResponse; -import com.moing.backend.domain.team.domain.service.TeamGetService; -import com.moing.backend.domain.team.domain.service.TeamUpdateService; -import com.moing.backend.global.config.fcm.dto.event.SingleFcmEvent; -import lombok.RequiredArgsConstructor; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.stereotype.Service; - -import javax.transaction.Transactional; -import java.util.List; - -import static com.moing.backend.domain.history.domain.entity.PagePath.HOME_PATH; -import static com.moing.backend.global.config.fcm.constant.ApproveTeamMessage.APPROVE_TEAM_MESSAGE; - -@Service -@RequiredArgsConstructor -@Transactional -public class ApproveTeamUseCase { - - private final TeamUpdateService teamUpdateService; - private final TeamGetService teamGetService; - private final ApplicationEventPublisher eventPublisher; - - public void approveTeams(List teamIds){ - teamUpdateService.updateTeamStatus(true, teamIds); - List leaderInfos=teamGetService.getLeaderInfoResponses(teamIds); - for(GetLeaderInfoResponse info: leaderInfos){ - String title=APPROVE_TEAM_MESSAGE.title(info.getLeaderName(), info.getTeamName()); - String body= APPROVE_TEAM_MESSAGE.body(); - -// eventPublisher.publishEvent(new SingleFcmEvent(info.getLeaderFcmToken(), title, body, info.getLeaderId(), "", info.getTeamName(), AlarmType.APPROVE_TEAM, HOME_PATH.getValue())); - } - } -} diff --git a/src/main/java/com/moing/backend/domain/team/presentation/AdminTeamController.java b/src/main/java/com/moing/backend/domain/team/presentation/AdminTeamController.java deleted file mode 100644 index 79b9421a..00000000 --- a/src/main/java/com/moing/backend/domain/team/presentation/AdminTeamController.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.moing.backend.domain.team.presentation; - -import com.moing.backend.domain.team.application.dto.response.GetNewTeamResponse; -import com.moing.backend.domain.team.application.service.ApproveTeamUseCase; -import com.moing.backend.domain.team.application.service.GetTeamUseCase; -import com.moing.backend.domain.team.application.service.RejectTeamUseCase; -import com.moing.backend.global.response.SuccessResponse; -import lombok.AllArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -import static com.moing.backend.domain.team.presentation.constant.TeamResponseMessage.*; - -@RestController -@AllArgsConstructor -@RequestMapping("/api/admin/team") -public class AdminTeamController { - - - private final ApproveTeamUseCase approveTeamUseCase; - private final RejectTeamUseCase rejectTeamUseCase; - private final GetTeamUseCase getTeamUseCase; - - /** - * 소모임 승인 - * [POST] api/admin/team/approval??teamIds=1,2,3 - * 작성자 : 김민수 - */ - - @PostMapping("/approval") - public ResponseEntity sendApproveAlarm(@RequestParam List teamIds) { - this.approveTeamUseCase.approveTeams(teamIds); - return ResponseEntity.ok(SuccessResponse.create(SEND_APPROVAL_ALARM_SUCCESS.getMessage())); - } - - /** - * 소모임 반려 - * [POST] api/admin/team/rejection?teamIds=1,2,3 - * 작성자: 김민수 - */ - @PostMapping("/rejection") - public ResponseEntity sendRejectionAlarm(@RequestParam List teamIds) { - this.rejectTeamUseCase.rejectTeams(teamIds); - return ResponseEntity.ok(SuccessResponse.create(SEND_REJECTION_ALARM_SUCCESS.getMessage())); - } - - /** - * 소모임 전체 조회 - */ - @GetMapping - public ResponseEntity>> getNewTeam(@RequestParam(value = "dateSort", defaultValue = "asc") String dateSort, - Pageable pageable) { - return ResponseEntity.ok(SuccessResponse.create(GET_NEW_TEAM_SUCCESS.getMessage(), this.getTeamUseCase.getNewTeam(dateSort, pageable))); - } - -} From 1dbb2cea0dcb291ff4fff1329b0b83ff1d5f09cf Mon Sep 17 00:00:00 2001 From: minsu20 Date: Mon, 29 Jan 2024 18:11:53 +0900 Subject: [PATCH 5/9] =?UTF-8?q?MNG-01=20fix:=20synchronized=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/service/BoardReadSaveService.java | 10 ++++------ .../domain/team/application/mapper/TeamMapper.java | 10 +++++----- .../domain/service/TeamMemberSaveService.java | 14 ++++++-------- .../application/mapper/TeamScoreMapper.java | 2 +- 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/moing/backend/domain/boardRead/domain/service/BoardReadSaveService.java b/src/main/java/com/moing/backend/domain/boardRead/domain/service/BoardReadSaveService.java index 563cc991..2ea4112e 100644 --- a/src/main/java/com/moing/backend/domain/boardRead/domain/service/BoardReadSaveService.java +++ b/src/main/java/com/moing/backend/domain/boardRead/domain/service/BoardReadSaveService.java @@ -18,13 +18,11 @@ public class BoardReadSaveService { public void saveBoardRead(Board board, BoardRead boardRead) { - synchronized (this) { - List existingBoardReads = boardReadRepository.findBoardReadByBoardAndMemberAndTeam(board, boardRead.getMember(), boardRead.getTeam()); + List existingBoardReads = boardReadRepository.findBoardReadByBoardAndMemberAndTeam(board, boardRead.getMember(), boardRead.getTeam()); - if (existingBoardReads.isEmpty()) { - boardRead.updateBoard(board); - boardReadRepository.save(boardRead); - } + if (existingBoardReads.isEmpty()) { + boardRead.updateBoard(board); + boardReadRepository.save(boardRead); } } } diff --git a/src/main/java/com/moing/backend/domain/team/application/mapper/TeamMapper.java b/src/main/java/com/moing/backend/domain/team/application/mapper/TeamMapper.java index 081a39a2..6f7a8d98 100644 --- a/src/main/java/com/moing/backend/domain/team/application/mapper/TeamMapper.java +++ b/src/main/java/com/moing/backend/domain/team/application/mapper/TeamMapper.java @@ -16,7 +16,7 @@ @Component public class TeamMapper { - public Team createTeam(CreateTeamRequest createTeamRequest, Member member) { + public static Team createTeam(CreateTeamRequest createTeamRequest, Member member) { return Team.builder() .category(Enum.valueOf(Category.class, createTeamRequest.getCategory())) .name(createTeamRequest.getName()) @@ -30,7 +30,7 @@ public Team createTeam(CreateTeamRequest createTeamRequest, Member member) { .build(); } - public GetTeamDetailResponse toTeamDetailResponse(Long memberId, Team team, Integer boardNum, List teamMemberInfoList) { + public static GetTeamDetailResponse toTeamDetailResponse(Long memberId, Team team, Integer boardNum, List teamMemberInfoList) { TeamInfo teamInfo = new TeamInfo(team.isDeleted(), team.getDeletionTime(), team.getName(), teamMemberInfoList.size(), team.getCategory(), team.getIntroduction(), memberId, teamMemberInfoList); return GetTeamDetailResponse.builder() .boardNum(boardNum) @@ -38,7 +38,7 @@ public GetTeamDetailResponse toTeamDetailResponse(Long memberId, Team team, Inte .build(); } - public ReviewTeamResponse toReviewTeamResponse(Long numOfMission, Team team, boolean isLeader, String memberName){ + public static ReviewTeamResponse toReviewTeamResponse(Long numOfMission, Team team, boolean isLeader, String memberName){ return ReviewTeamResponse .builder() .teamId(team.getTeamId()) @@ -52,7 +52,7 @@ public ReviewTeamResponse toReviewTeamResponse(Long numOfMission, Team team, boo .build(); } - public Long calculateDuration(LocalDateTime approvalTime) { + public static Long calculateDuration(LocalDateTime approvalTime) { ZoneId seoulZoneId = ZoneId.of("Asia/Seoul"); LocalDateTime currentDateTime = LocalDateTime.now(seoulZoneId); @@ -62,7 +62,7 @@ public Long calculateDuration(LocalDateTime approvalTime) { return daysBetween; } - public GetCurrentStatusResponse toCurrentStatusResponse(Team team) { + public static GetCurrentStatusResponse toCurrentStatusResponse(Team team) { return GetCurrentStatusResponse.builder() .name(team.getName()) .introduction(team.getIntroduction()) diff --git a/src/main/java/com/moing/backend/domain/teamMember/domain/service/TeamMemberSaveService.java b/src/main/java/com/moing/backend/domain/teamMember/domain/service/TeamMemberSaveService.java index a1a7090b..8aff52e7 100644 --- a/src/main/java/com/moing/backend/domain/teamMember/domain/service/TeamMemberSaveService.java +++ b/src/main/java/com/moing/backend/domain/teamMember/domain/service/TeamMemberSaveService.java @@ -19,14 +19,12 @@ public class TeamMemberSaveService { private final TeamMemberRepository teamMemberRepository; public void addTeamMember(Team team, Member member) { - synchronized (this) { - Optional teamMember = teamMemberRepository.findTeamMemberByTeamAndMember(team, member); - checkDeletion(team); - if (teamMember.isPresent()) { - handleExistingMember(teamMember.get()); - } else { - addNewTeamMember(team, member); - } + Optional teamMember = teamMemberRepository.findTeamMemberByTeamAndMember(team, member); + checkDeletion(team); + if (teamMember.isPresent()) { + handleExistingMember(teamMember.get()); + } else { + addNewTeamMember(team, member); } } diff --git a/src/main/java/com/moing/backend/domain/teamScore/application/mapper/TeamScoreMapper.java b/src/main/java/com/moing/backend/domain/teamScore/application/mapper/TeamScoreMapper.java index 49031bc2..7b02e363 100644 --- a/src/main/java/com/moing/backend/domain/teamScore/application/mapper/TeamScoreMapper.java +++ b/src/main/java/com/moing/backend/domain/teamScore/application/mapper/TeamScoreMapper.java @@ -8,7 +8,7 @@ @Component public class TeamScoreMapper { - public TeamScore mapToTeamScore(Team team) { + public static TeamScore mapToTeamScore(Team team) { return TeamScore.builder() .score(0L) .level(1L) From 3f24ce812b97389b55c7c7194a2733fe4d6fb74a Mon Sep 17 00:00:00 2001 From: minsu20 Date: Mon, 29 Jan 2024 18:12:22 +0900 Subject: [PATCH 6/9] =?UTF-8?q?MNG-01=20refactor:=20=ED=8C=80=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EB=A1=9C=EC=A7=81=20=ED=95=A8=EC=88=98=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CreateTeamUseCase.java | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/moing/backend/domain/team/application/service/CreateTeamUseCase.java b/src/main/java/com/moing/backend/domain/team/application/service/CreateTeamUseCase.java index 027838c4..aa8d49d4 100644 --- a/src/main/java/com/moing/backend/domain/team/application/service/CreateTeamUseCase.java +++ b/src/main/java/com/moing/backend/domain/team/application/service/CreateTeamUseCase.java @@ -25,21 +25,27 @@ public class CreateTeamUseCase { private final MemberGetService memberGetService; private final TeamSaveService teamSaveService; private final TeamMemberSaveService teamMemberSaveService; - private final TeamMapper teamMapper; private final TeamScoreSaveService teamScoreSaveService; - private final TeamScoreMapper teamScoreMapper; private final ApplicationEventPublisher eventPublisher; public CreateTeamResponse createTeam(CreateTeamRequest createTeamRequest, String socialId){ Member member = memberGetService.getMemberBySocialId(socialId); - Team team=teamMapper.createTeam(createTeamRequest, member); + Team team = createAndSaveTeam(createTeamRequest, member); + publishTeamCreateEvent(team); + return new CreateTeamResponse(team.getTeamId()); + } + + private Team createAndSaveTeam(CreateTeamRequest createTeamRequest, Member member) { + Team team = TeamMapper.createTeam(createTeamRequest, member); teamSaveService.saveTeam(team); teamMemberSaveService.addTeamMember(team, member); - //====지워야 함 (테스트 용)===== - team.approveTeam(); - //====지워야 함 (테스트 용)===== - teamScoreSaveService.save(teamScoreMapper.mapToTeamScore(team)); // 팀스코어 엔티티 생성 + team.approveTeam(); // 승인 처리 + teamScoreSaveService.save(TeamScoreMapper.mapToTeamScore(team)); + return team; + } + + private void publishTeamCreateEvent(Team team) { eventPublisher.publishEvent(new TeamCreateEvent(team.getName(), team.getLeaderId())); - return new CreateTeamResponse(team.getTeamId()); } } + From d049dc06652596c5192d7e930bbce8d055663f2d Mon Sep 17 00:00:00 2001 From: minsu20 Date: Mon, 29 Jan 2024 18:32:50 +0900 Subject: [PATCH 7/9] =?UTF-8?q?MNG-02=20fix:=20=ED=8C=80=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EC=95=8C=EB=A6=BC=20=EC=9A=B4=EC=98=81=20=EA=B3=84?= =?UTF-8?q?=EC=A0=95=EC=97=90=EC=84=9C=EB=A7=8C=20=EC=95=8C=EB=A6=BC=20?= =?UTF-8?q?=EA=B0=80=EA=B2=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/global/config/slack/team/TeamCreateHandler.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/moing/backend/global/config/slack/team/TeamCreateHandler.java b/src/main/java/com/moing/backend/global/config/slack/team/TeamCreateHandler.java index 34bcad01..0481017d 100644 --- a/src/main/java/com/moing/backend/global/config/slack/team/TeamCreateHandler.java +++ b/src/main/java/com/moing/backend/global/config/slack/team/TeamCreateHandler.java @@ -3,12 +3,14 @@ import com.moing.backend.global.config.slack.team.dto.TeamCreateEvent; import com.moing.backend.global.config.slack.util.WebhookUtil; import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Profile; import org.springframework.context.event.EventListener; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; @RequiredArgsConstructor @Component +@Profile("prod") public class TeamCreateHandler { private final WebhookUtil webhookUtil; From 2671376ac70e3f77b2a0121bcfe1bf990debec97 Mon Sep 17 00:00:00 2001 From: minsu20 Date: Mon, 29 Jan 2024 18:54:28 +0900 Subject: [PATCH 8/9] =?UTF-8?q?MNG-02=20fix:=20=EC=95=8C=EB=A6=BC=EC=84=BC?= =?UTF-8?q?=ED=84=B0=EC=97=90=EC=84=9C=20=ED=91=B8=EC=8B=9C=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=EC=9D=84=20=ED=81=B4=EB=A6=AD=ED=96=88=EC=9D=84=20?= =?UTF-8?q?=EB=95=8C=20=EC=9D=B4=EB=8F=99=ED=95=98=EA=B2=8C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/config/fcm/service/FcmService.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/moing/backend/global/config/fcm/service/FcmService.java b/src/main/java/com/moing/backend/global/config/fcm/service/FcmService.java index 37983a5c..16ad947e 100644 --- a/src/main/java/com/moing/backend/global/config/fcm/service/FcmService.java +++ b/src/main/java/com/moing/backend/global/config/fcm/service/FcmService.java @@ -17,7 +17,9 @@ import javax.transaction.Transactional; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; @Service @Transactional @@ -55,16 +57,20 @@ public SingleResponse sendSingleDevice(SingleRequest toSingleRequest) { .build()) .build(); + Map additionalData = new HashMap<>(); + additionalData.put("path", toSingleRequest.getPath()); + additionalData.put("idInfo", toSingleRequest.getIdInfo()); + Message message = Message.builder() .setToken(toSingleRequest.getRegistrationToken()) .setNotification(notification) .setAndroidConfig(androidConfig) // Applying Android configuration .setApnsConfig(apnsConfig) // Applying APNs configuration + .putAllData(additionalData) .build(); try { String response = firebaseMessaging.send(message); -// saveSingleAlarmHistoryUseCase.saveAlarmHistory(toSingleRequest.getMemberId(), toSingleRequest.getIdInfo(), toSingleRequest.getTitle(), toSingleRequest.getBody(), toSingleRequest.getName(), toSingleRequest.getAlarmType(), toSingleRequest.getPath()); return new SingleResponse(response); } catch (FirebaseMessagingException e) { throw handleException(e); @@ -103,11 +109,16 @@ public MultiResponse sendMultipleDevices(MultiRequest toMultiRequest) { .build()) .build(); + Map additionalData = new HashMap<>(); + additionalData.put("path", toMultiRequest.getPath()); + additionalData.put("idInfo", toMultiRequest.getIdInfo()); + MulticastMessage message = MulticastMessage.builder() .addAllTokens(fcmTokens) .setNotification(notification) .setAndroidConfig(androidConfig) // Applying Android configuration .setApnsConfig(apnsConfig) // Applying APNs configuration + .putAllData(additionalData) .build(); try { From fde64d0cce6e1f3b3c673030a321b98c73dee8bb Mon Sep 17 00:00:00 2001 From: minsu20 Date: Tue, 30 Jan 2024 11:16:51 +0900 Subject: [PATCH 9/9] =?UTF-8?q?MNG-02=20refactor:=20fcm=20=EB=B6=80?= =?UTF-8?q?=EB=B6=84=20=EC=B6=94=EC=83=81=ED=99=94=EA=B2=8C=20=EC=9D=98?= =?UTF-8?q?=EC=A1=B4=ED=95=98=EA=B2=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/MultiAlarmEventUseCase.java | 31 ++ .../application/SingleAlarmEventUseCase.java | 29 ++ .../service/FireThrowAlarmUseCase.java | 4 - .../service/MissionRemindAlarmUseCase.java | 14 +- .../fcm/exception/ExceptionHandler.java | 25 ++ .../global/config/fcm/service/FcmService.java | 348 +++++++++--------- .../config/fcm/service/MessageSender.java | 5 + .../fcm/service/MultiMessageSender.java | 100 +++++ .../fcm/service/SingleMessageSender.java | 73 ++++ .../config/fcm/util/FcmMessageUtil.java | 88 ++--- 10 files changed, 486 insertions(+), 231 deletions(-) create mode 100644 src/main/java/com/moing/backend/domain/alarm/application/MultiAlarmEventUseCase.java create mode 100644 src/main/java/com/moing/backend/domain/alarm/application/SingleAlarmEventUseCase.java create mode 100644 src/main/java/com/moing/backend/global/config/fcm/exception/ExceptionHandler.java create mode 100644 src/main/java/com/moing/backend/global/config/fcm/service/MessageSender.java create mode 100644 src/main/java/com/moing/backend/global/config/fcm/service/MultiMessageSender.java create mode 100644 src/main/java/com/moing/backend/global/config/fcm/service/SingleMessageSender.java diff --git a/src/main/java/com/moing/backend/domain/alarm/application/MultiAlarmEventUseCase.java b/src/main/java/com/moing/backend/domain/alarm/application/MultiAlarmEventUseCase.java new file mode 100644 index 00000000..f9eed763 --- /dev/null +++ b/src/main/java/com/moing/backend/domain/alarm/application/MultiAlarmEventUseCase.java @@ -0,0 +1,31 @@ +package com.moing.backend.domain.alarm.application; + +import com.moing.backend.domain.history.application.mapper.AlarmHistoryMapper; +import com.moing.backend.domain.history.application.service.SaveMultiAlarmHistoryUseCase; +import com.moing.backend.global.config.fcm.dto.event.MultiFcmEvent; +import com.moing.backend.global.config.fcm.dto.request.MultiRequest; +import com.moing.backend.global.config.fcm.service.MultiMessageSender; +import lombok.RequiredArgsConstructor; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + + +@Component +@RequiredArgsConstructor +public class MultiAlarmEventUseCase { + + private final MultiMessageSender multiMessageSender; + private final SaveMultiAlarmHistoryUseCase saveMultiAlarmHistoryUseCase; + + @Async + @EventListener + public void onMultiAlarmEvent(MultiFcmEvent event) { + if (event.getIdAndTokensByPush().isPresent() && !event.getIdAndTokensByPush().get().isEmpty()) { + multiMessageSender.send(new MultiRequest(event.getIdAndTokensByPush().get(), event.getTitle(), event.getBody(), event.getIdInfo(), event.getName(), event.getAlarmType(), event.getPath())); + } + if (event.getIdAndTokensBySave().isPresent() && !event.getIdAndTokensBySave().get().isEmpty()) { + saveMultiAlarmHistoryUseCase.saveAlarmHistories(AlarmHistoryMapper.getMemberIds(event.getIdAndTokensBySave().get()), event.getIdInfo(), event.getTitle(), event.getBody(), event.getName(), event.getAlarmType(), event.getPath()); + } + } +} diff --git a/src/main/java/com/moing/backend/domain/alarm/application/SingleAlarmEventUseCase.java b/src/main/java/com/moing/backend/domain/alarm/application/SingleAlarmEventUseCase.java new file mode 100644 index 00000000..514d64fb --- /dev/null +++ b/src/main/java/com/moing/backend/domain/alarm/application/SingleAlarmEventUseCase.java @@ -0,0 +1,29 @@ +package com.moing.backend.domain.alarm.application; + +import com.moing.backend.domain.history.application.service.SaveSingleAlarmHistoryUseCase; +import com.moing.backend.global.config.fcm.dto.event.SingleFcmEvent; +import com.moing.backend.global.config.fcm.dto.request.SingleRequest; +import com.moing.backend.global.config.fcm.service.SingleMessageSender; +import lombok.RequiredArgsConstructor; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + + +@Component +@RequiredArgsConstructor +public class SingleAlarmEventUseCase { + + private final SingleMessageSender singleMessageSender; + private final SaveSingleAlarmHistoryUseCase saveSingleAlarmHistoryUseCase; + + @Async + @EventListener + public void onSingleAlarmEvent(SingleFcmEvent event) { + if (event.getMember().isFirePush() && !event.getMember().isSignOut()) { //알림 on, 로그아웃 안함 + singleMessageSender.send(new SingleRequest(event.getMember().getFcmToken(), event.getTitle(), event.getBody(), event.getMember().getMemberId(), event.getIdInfo(), event.getName(), event.getAlarmType(), event.getPath())); + } + saveSingleAlarmHistoryUseCase.saveAlarmHistory(event.getMember().getMemberId(), event.getIdInfo(), event.getTitle(), event.getBody(), event.getName(), event.getAlarmType(), event.getPath()); + } + +} diff --git a/src/main/java/com/moing/backend/domain/fire/application/service/FireThrowAlarmUseCase.java b/src/main/java/com/moing/backend/domain/fire/application/service/FireThrowAlarmUseCase.java index c76c180b..03b2d1bb 100644 --- a/src/main/java/com/moing/backend/domain/fire/application/service/FireThrowAlarmUseCase.java +++ b/src/main/java/com/moing/backend/domain/fire/application/service/FireThrowAlarmUseCase.java @@ -5,9 +5,7 @@ import com.moing.backend.domain.mission.domain.entity.Mission; import com.moing.backend.domain.mission.domain.entity.constant.MissionType; import com.moing.backend.domain.team.domain.entity.Team; -import com.moing.backend.domain.teamMember.domain.service.TeamMemberGetService; import com.moing.backend.global.config.fcm.dto.event.SingleFcmEvent; -import com.moing.backend.global.config.fcm.service.FcmService; import lombok.RequiredArgsConstructor; import net.minidev.json.JSONObject; import org.springframework.context.ApplicationEventPublisher; @@ -24,9 +22,7 @@ @RequiredArgsConstructor public class FireThrowAlarmUseCase { - private final FcmService fcmService; private final ApplicationEventPublisher eventPublisher; - private final TeamMemberGetService teamMemberGetService; public void sendFireThrowAlarm(Member throwMember, Member receiveMember, Team team, Mission mission) { diff --git a/src/main/java/com/moing/backend/domain/mission/application/service/MissionRemindAlarmUseCase.java b/src/main/java/com/moing/backend/domain/mission/application/service/MissionRemindAlarmUseCase.java index dd0a0e8f..5bcfa309 100644 --- a/src/main/java/com/moing/backend/domain/mission/application/service/MissionRemindAlarmUseCase.java +++ b/src/main/java/com/moing/backend/domain/mission/application/service/MissionRemindAlarmUseCase.java @@ -6,16 +6,12 @@ import com.moing.backend.domain.history.domain.entity.AlarmType; import com.moing.backend.domain.history.domain.entity.PagePath; import com.moing.backend.domain.member.domain.entity.Member; -import com.moing.backend.domain.mission.domain.entity.Mission; import com.moing.backend.domain.mission.domain.entity.constant.MissionStatus; import com.moing.backend.domain.mission.domain.service.MissionQueryService; import com.moing.backend.domain.missionArchive.domain.service.MissionArchiveScheduleQueryService; -import com.moing.backend.domain.teamMember.domain.service.TeamMemberGetService; -import com.moing.backend.global.config.fcm.dto.event.MultiFcmEvent; import com.moing.backend.global.config.fcm.dto.request.MultiRequest; -import com.moing.backend.global.config.fcm.service.FcmService; +import com.moing.backend.global.config.fcm.service.MultiMessageSender; import lombok.RequiredArgsConstructor; -import net.minidev.json.JSONObject; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; @@ -37,7 +33,7 @@ public class MissionRemindAlarmUseCase { private final MissionQueryService missionQueryService; private final ApplicationEventPublisher eventPublisher; - private final FcmService fcmService; + private final MultiMessageSender multiMessageSender; private final SaveMultiAlarmHistoryUseCase saveMultiAlarmHistoryUseCase; String REMIND_NAME = "미션 리마인드"; @@ -58,7 +54,7 @@ public Boolean sendRemindMissionAlarm() { // "",REMIND_NAME, AlarmType.REMIND, PagePath.MISSION_ALL_PTAH.getValue())); if (pushMemberIdAndToken.isPresent() && !pushMemberIdAndToken.get().isEmpty()) { - fcmService.sendMultipleDevices(new MultiRequest(pushMemberIdAndToken.get(), title,message, "",REMIND_NAME, AlarmType.REMIND, PagePath.MISSION_ALL_PTAH.getValue())); + multiMessageSender.send(new MultiRequest(pushMemberIdAndToken.get(), title, message, "", REMIND_NAME, AlarmType.REMIND, PagePath.MISSION_ALL_PTAH.getValue())); } if (memberIdAndTokens.isPresent() && !memberIdAndTokens.get().isEmpty()) { saveMultiAlarmHistoryUseCase.saveAlarmHistories(AlarmHistoryMapper.getMemberIds(memberIdAndTokens.get()),"",title,message,REMIND_NAME, AlarmType.REMIND, PagePath.MISSION_ALL_PTAH.getValue()); @@ -108,7 +104,7 @@ public Boolean sendRepeatMissionRemindOnSunday() { Optional> pushMemberIdAndToken = isPushMemberIdAndToken(repeatMissionByStatus); if (pushMemberIdAndToken.isPresent() && !pushMemberIdAndToken.get().isEmpty()) { - fcmService.sendMultipleDevices(new MultiRequest(pushMemberIdAndToken.get(), title,message, "",REMIND_NAME, AlarmType.REMIND, PagePath.MISSION_ALL_PTAH.getValue())); + multiMessageSender.send(new MultiRequest(pushMemberIdAndToken.get(), title, message, "", REMIND_NAME, AlarmType.REMIND, PagePath.MISSION_ALL_PTAH.getValue())); } if (memberIdAndTokens.isPresent() && !memberIdAndTokens.get().isEmpty()) { saveMultiAlarmHistoryUseCase.saveAlarmHistories(AlarmHistoryMapper.getMemberIds(memberIdAndTokens.get()), "", title, message, REMIND_NAME, AlarmType.REMIND, PagePath.MISSION_ALL_PTAH.getValue()); @@ -130,7 +126,7 @@ public Boolean sendRepeatMissionRemindOnMonday() { Optional> pushMemberIdAndToken = isPushMemberIdAndToken(repeatMissionByStatus); if (pushMemberIdAndToken.isPresent() && !pushMemberIdAndToken.get().isEmpty()) { - fcmService.sendMultipleDevices(new MultiRequest(pushMemberIdAndToken.get(), title,message, "",REMIND_NAME, AlarmType.REMIND, PagePath.MISSION_ALL_PTAH.getValue())); + multiMessageSender.send(new MultiRequest(pushMemberIdAndToken.get(), title, message, "", REMIND_NAME, AlarmType.REMIND, PagePath.MISSION_ALL_PTAH.getValue())); } if (memberIdAndTokens.isPresent() && !memberIdAndTokens.get().isEmpty()) { saveMultiAlarmHistoryUseCase.saveAlarmHistories(AlarmHistoryMapper.getMemberIds(memberIdAndTokens.get()), "", title, message, REMIND_NAME, AlarmType.REMIND, PagePath.MISSION_ALL_PTAH.getValue()); diff --git a/src/main/java/com/moing/backend/global/config/fcm/exception/ExceptionHandler.java b/src/main/java/com/moing/backend/global/config/fcm/exception/ExceptionHandler.java new file mode 100644 index 00000000..b495c41a --- /dev/null +++ b/src/main/java/com/moing/backend/global/config/fcm/exception/ExceptionHandler.java @@ -0,0 +1,25 @@ +package com.moing.backend.global.config.fcm.exception; + +import com.google.firebase.messaging.FirebaseMessagingException; + +public class ExceptionHandler { + + public static NotificationException handleFirebaseMessagingException(FirebaseMessagingException e) { + String errorCode = e.getErrorCode().name(); + String errorMessage = e.getMessage(); + + switch (errorCode) { + case "INVALID_ARGUMENT": + return new NotificationException("올바르지 않은 인자 값입니다: " + errorMessage); + case "NOT_FOUND": + return new NotificationException("등록 토큰이 유효하지 않거나, 주제(Topic)가 존재하지 않습니다: " + errorMessage); + case "UNREGISTERED": + return new NotificationException("해당 주제(Topic)의 구독이 해지되었습니다: " + errorMessage); + case "UNAVAILABLE": + return new NotificationException("서비스를 사용할 수 없습니다: " + errorMessage); + default: + return new NotificationException("메시지 전송에 실패했습니다: " + errorMessage); + } + } +} + diff --git a/src/main/java/com/moing/backend/global/config/fcm/service/FcmService.java b/src/main/java/com/moing/backend/global/config/fcm/service/FcmService.java index 16ad947e..6deaf58d 100644 --- a/src/main/java/com/moing/backend/global/config/fcm/service/FcmService.java +++ b/src/main/java/com/moing/backend/global/config/fcm/service/FcmService.java @@ -1,174 +1,174 @@ -package com.moing.backend.global.config.fcm.service; - -import com.google.firebase.messaging.*; -import com.moing.backend.domain.history.application.mapper.AlarmHistoryMapper; -import com.moing.backend.domain.history.application.service.SaveMultiAlarmHistoryUseCase; -import com.moing.backend.domain.history.application.service.SaveSingleAlarmHistoryUseCase; -import com.moing.backend.global.config.fcm.dto.request.MultiRequest; -import com.moing.backend.global.config.fcm.dto.request.SingleRequest; -import com.moing.backend.global.config.fcm.dto.response.MultiResponse; -import com.moing.backend.global.config.fcm.dto.response.SingleResponse; -import com.moing.backend.global.config.fcm.exception.NotificationException; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.retry.annotation.Backoff; -import org.springframework.retry.annotation.Retryable; -import org.springframework.stereotype.Service; - -import javax.transaction.Transactional; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@Service -@Transactional -@RequiredArgsConstructor -@Slf4j -public class FcmService { - - private final FirebaseMessaging firebaseMessaging; - @Retryable(value = FirebaseMessagingException.class, maxAttempts = 3, backoff = @Backoff(delay = 1000)) - public SingleResponse sendSingleDevice(SingleRequest toSingleRequest) { - - Notification notification = Notification.builder() - .setTitle(toSingleRequest.getTitle()) - .setBody(toSingleRequest.getBody()) - .build(); - - // Android Configuration - AndroidConfig androidConfig = AndroidConfig.builder() - .setPriority(AndroidConfig.Priority.HIGH) - .setNotification(AndroidNotification.builder() - .setChannelId("FCM_Channel") - .setTitle(toSingleRequest.getTitle()) - .setBody(toSingleRequest.getBody()) - .build()) - .build(); - - // APNs Configuration - ApnsConfig apnsConfig = ApnsConfig.builder() - .setAps(Aps.builder() - .setCategory("YOUR_CATEGORY") // Replace with your category - .setAlert(ApsAlert.builder() - .setTitle(toSingleRequest.getTitle()) - .setBody(toSingleRequest.getBody()) - .build()) - .build()) - .build(); - - Map additionalData = new HashMap<>(); - additionalData.put("path", toSingleRequest.getPath()); - additionalData.put("idInfo", toSingleRequest.getIdInfo()); - - Message message = Message.builder() - .setToken(toSingleRequest.getRegistrationToken()) - .setNotification(notification) - .setAndroidConfig(androidConfig) // Applying Android configuration - .setApnsConfig(apnsConfig) // Applying APNs configuration - .putAllData(additionalData) - .build(); - - try { - String response = firebaseMessaging.send(message); - return new SingleResponse(response); - } catch (FirebaseMessagingException e) { - throw handleException(e); - } - } - - - @Retryable(value = FirebaseMessagingException.class, maxAttempts = 3, backoff = @Backoff(delay = 1000)) - public MultiResponse sendMultipleDevices(MultiRequest toMultiRequest) { - - - List fcmTokens = AlarmHistoryMapper.getFcmTokens(toMultiRequest.getMemberIdAndTokens()); - Notification notification = Notification.builder() - .setTitle(toMultiRequest.getTitle()) - .setBody(toMultiRequest.getBody()) - .build(); - - // Android Configuration - AndroidConfig androidConfig = AndroidConfig.builder() - .setPriority(AndroidConfig.Priority.HIGH) - .setNotification(AndroidNotification.builder() - .setChannelId("FCM_Channel") - .setTitle(toMultiRequest.getTitle()) - .setBody(toMultiRequest.getBody()) - .build()) - .build(); - - // APNs Configuration - ApnsConfig apnsConfig = ApnsConfig.builder() - .setAps(Aps.builder() - .setCategory("YOUR_CATEGORY") // Replace with your category - .setAlert(ApsAlert.builder() - .setTitle(toMultiRequest.getTitle()) - .setBody(toMultiRequest.getBody()) - .build()) - .build()) - .build(); - - Map additionalData = new HashMap<>(); - additionalData.put("path", toMultiRequest.getPath()); - additionalData.put("idInfo", toMultiRequest.getIdInfo()); - - MulticastMessage message = MulticastMessage.builder() - .addAllTokens(fcmTokens) - .setNotification(notification) - .setAndroidConfig(androidConfig) // Applying Android configuration - .setApnsConfig(apnsConfig) // Applying APNs configuration - .putAllData(additionalData) - .build(); - - try { - BatchResponse response = firebaseMessaging.sendMulticast(message); - - - List failedTokens = new ArrayList<>(); - - if (response.getFailureCount() > 0) { - List responses = response.getResponses(); - - List memberIds = AlarmHistoryMapper.getMemberIds(toMultiRequest.getMemberIdAndTokens()); - - for (int i = 0; i < responses.size(); i++) { - if (!responses.get(i).isSuccessful()) { - // Add the failed tokens to the list - failedTokens.add(fcmTokens.get(i)); - } - } - } - - String messageString = String.format("%d messages were sent successfully.", response.getSuccessCount()); - - return new MultiResponse(messageString, failedTokens); - - } catch (FirebaseMessagingException e) { - throw handleException(e); - } - } - - - - private NotificationException handleException(FirebaseMessagingException e) { - String errorCode = e.getErrorCode().name(); - String errorMessage = e.getMessage(); - - switch (errorCode) { - case "INVALID_ARGUMENT": - return new NotificationException("올바르지 않은 인자 값입니다: " + errorMessage); - case "NOT_FOUND": - return new NotificationException("등록 토큰이 유효하지 않거나, 주제(Topic)가 존재하지 않습니다: " + errorMessage); - case "UNREGISTERED": - return new NotificationException("해당 주제(Topic)의 구독이 해지되었습니다: " + errorMessage); - case "UNAVAILABLE": - return new NotificationException("서비스를 사용할 수 없습니다: " + errorMessage); - default: - return new NotificationException("메시지 전송에 실패했습니다: " + errorMessage); - } - } - -} - - +//package com.moing.backend.global.config.fcm.service; +// +//import com.google.firebase.messaging.*; +//import com.moing.backend.domain.history.application.mapper.AlarmHistoryMapper; +//import com.moing.backend.domain.history.application.service.SaveMultiAlarmHistoryUseCase; +//import com.moing.backend.domain.history.application.service.SaveSingleAlarmHistoryUseCase; +//import com.moing.backend.global.config.fcm.dto.request.MultiRequest; +//import com.moing.backend.global.config.fcm.dto.request.SingleRequest; +//import com.moing.backend.global.config.fcm.dto.response.MultiResponse; +//import com.moing.backend.global.config.fcm.dto.response.SingleResponse; +//import com.moing.backend.global.config.fcm.exception.NotificationException; +//import lombok.RequiredArgsConstructor; +//import lombok.extern.slf4j.Slf4j; +//import org.springframework.retry.annotation.Backoff; +//import org.springframework.retry.annotation.Retryable; +//import org.springframework.stereotype.Service; +// +//import javax.transaction.Transactional; +//import java.util.ArrayList; +//import java.util.HashMap; +//import java.util.List; +//import java.util.Map; +// +//@Service +//@Transactional +//@RequiredArgsConstructor +//@Slf4j +//public class FcmService { +// +// private final FirebaseMessaging firebaseMessaging; +// @Retryable(value = FirebaseMessagingException.class, maxAttempts = 3, backoff = @Backoff(delay = 1000)) +// public SingleResponse sendSingleDevice(SingleRequest toSingleRequest) { +// +// Notification notification = Notification.builder() +// .setTitle(toSingleRequest.getTitle()) +// .setBody(toSingleRequest.getBody()) +// .build(); +// +// // Android Configuration +// AndroidConfig androidConfig = AndroidConfig.builder() +// .setPriority(AndroidConfig.Priority.HIGH) +// .setNotification(AndroidNotification.builder() +// .setChannelId("FCM_Channel") +// .setTitle(toSingleRequest.getTitle()) +// .setBody(toSingleRequest.getBody()) +// .build()) +// .build(); +// +// // APNs Configuration +// ApnsConfig apnsConfig = ApnsConfig.builder() +// .setAps(Aps.builder() +// .setCategory("YOUR_CATEGORY") // Replace with your category +// .setAlert(ApsAlert.builder() +// .setTitle(toSingleRequest.getTitle()) +// .setBody(toSingleRequest.getBody()) +// .build()) +// .build()) +// .build(); +// +// Map additionalData = new HashMap<>(); +// additionalData.put("path", toSingleRequest.getPath()); +// additionalData.put("idInfo", toSingleRequest.getIdInfo()); +// +// Message message = Message.builder() +// .setToken(toSingleRequest.getRegistrationToken()) +// .setNotification(notification) +// .setAndroidConfig(androidConfig) // Applying Android configuration +// .setApnsConfig(apnsConfig) // Applying APNs configuration +// .putAllData(additionalData) +// .build(); +// +// try { +// String response = firebaseMessaging.send(message); +// return new SingleResponse(response); +// } catch (FirebaseMessagingException e) { +// throw handleException(e); +// } +// } +// +// +// @Retryable(value = FirebaseMessagingException.class, maxAttempts = 3, backoff = @Backoff(delay = 1000)) +// public MultiResponse sendMultipleDevices(MultiRequest toMultiRequest) { +// +// +// List fcmTokens = AlarmHistoryMapper.getFcmTokens(toMultiRequest.getMemberIdAndTokens()); +// Notification notification = Notification.builder() +// .setTitle(toMultiRequest.getTitle()) +// .setBody(toMultiRequest.getBody()) +// .build(); +// +// // Android Configuration +// AndroidConfig androidConfig = AndroidConfig.builder() +// .setPriority(AndroidConfig.Priority.HIGH) +// .setNotification(AndroidNotification.builder() +// .setChannelId("FCM_Channel") +// .setTitle(toMultiRequest.getTitle()) +// .setBody(toMultiRequest.getBody()) +// .build()) +// .build(); +// +// // APNs Configuration +// ApnsConfig apnsConfig = ApnsConfig.builder() +// .setAps(Aps.builder() +// .setCategory("YOUR_CATEGORY") // Replace with your category +// .setAlert(ApsAlert.builder() +// .setTitle(toMultiRequest.getTitle()) +// .setBody(toMultiRequest.getBody()) +// .build()) +// .build()) +// .build(); +// +// Map additionalData = new HashMap<>(); +// additionalData.put("path", toMultiRequest.getPath()); +// additionalData.put("idInfo", toMultiRequest.getIdInfo()); +// +// MulticastMessage message = MulticastMessage.builder() +// .addAllTokens(fcmTokens) +// .setNotification(notification) +// .setAndroidConfig(androidConfig) // Applying Android configuration +// .setApnsConfig(apnsConfig) // Applying APNs configuration +// .putAllData(additionalData) +// .build(); +// +// try { +// BatchResponse response = firebaseMessaging.sendMulticast(message); +// +// +// List failedTokens = new ArrayList<>(); +// +// if (response.getFailureCount() > 0) { +// List responses = response.getResponses(); +// +// List memberIds = AlarmHistoryMapper.getMemberIds(toMultiRequest.getMemberIdAndTokens()); +// +// for (int i = 0; i < responses.size(); i++) { +// if (!responses.get(i).isSuccessful()) { +// // Add the failed tokens to the list +// failedTokens.add(fcmTokens.get(i)); +// } +// } +// } +// +// String messageString = String.format("%d messages were sent successfully.", response.getSuccessCount()); +// +// return new MultiResponse(messageString, failedTokens); +// +// } catch (FirebaseMessagingException e) { +// throw handleException(e); +// } +// } +// +// +// +// private NotificationException handleException(FirebaseMessagingException e) { +// String errorCode = e.getErrorCode().name(); +// String errorMessage = e.getMessage(); +// +// switch (errorCode) { +// case "INVALID_ARGUMENT": +// return new NotificationException("올바르지 않은 인자 값입니다: " + errorMessage); +// case "NOT_FOUND": +// return new NotificationException("등록 토큰이 유효하지 않거나, 주제(Topic)가 존재하지 않습니다: " + errorMessage); +// case "UNREGISTERED": +// return new NotificationException("해당 주제(Topic)의 구독이 해지되었습니다: " + errorMessage); +// case "UNAVAILABLE": +// return new NotificationException("서비스를 사용할 수 없습니다: " + errorMessage); +// default: +// return new NotificationException("메시지 전송에 실패했습니다: " + errorMessage); +// } +// } +// +//} +// +// diff --git a/src/main/java/com/moing/backend/global/config/fcm/service/MessageSender.java b/src/main/java/com/moing/backend/global/config/fcm/service/MessageSender.java new file mode 100644 index 00000000..d6b73aeb --- /dev/null +++ b/src/main/java/com/moing/backend/global/config/fcm/service/MessageSender.java @@ -0,0 +1,5 @@ +package com.moing.backend.global.config.fcm.service; + +public interface MessageSender { + void send(T request); +} diff --git a/src/main/java/com/moing/backend/global/config/fcm/service/MultiMessageSender.java b/src/main/java/com/moing/backend/global/config/fcm/service/MultiMessageSender.java new file mode 100644 index 00000000..ec54e038 --- /dev/null +++ b/src/main/java/com/moing/backend/global/config/fcm/service/MultiMessageSender.java @@ -0,0 +1,100 @@ +package com.moing.backend.global.config.fcm.service; + +import com.google.firebase.messaging.*; +import com.moing.backend.domain.history.application.mapper.AlarmHistoryMapper; +import com.moing.backend.global.config.fcm.dto.request.MultiRequest; +import com.moing.backend.global.config.fcm.dto.response.MultiResponse; +import com.moing.backend.global.config.fcm.exception.ExceptionHandler; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.retry.annotation.Backoff; +import org.springframework.retry.annotation.Retryable; +import org.springframework.stereotype.Service; + +import javax.transaction.Transactional; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +@Transactional +@RequiredArgsConstructor +@Slf4j +public class MultiMessageSender implements MessageSender { + + private final FirebaseMessaging firebaseMessaging; + + @Override + @Retryable(value = FirebaseMessagingException.class, maxAttempts = 3, backoff = @Backoff(delay = 1000)) + public void send(MultiRequest request) { + + + List fcmTokens = AlarmHistoryMapper.getFcmTokens(request.getMemberIdAndTokens()); + Notification notification = Notification.builder() + .setTitle(request.getTitle()) + .setBody(request.getBody()) + .build(); + + // Android Configuration + AndroidConfig androidConfig = AndroidConfig.builder() + .setPriority(AndroidConfig.Priority.HIGH) + .setNotification(AndroidNotification.builder() + .setChannelId("FCM_Channel") + .setTitle(request.getTitle()) + .setBody(request.getBody()) + .build()) + .build(); + + // APNs Configuration + ApnsConfig apnsConfig = ApnsConfig.builder() + .setAps(Aps.builder() + .setCategory("YOUR_CATEGORY") // Replace with your category + .setAlert(ApsAlert.builder() + .setTitle(request.getTitle()) + .setBody(request.getBody()) + .build()) + .build()) + .build(); + + Map additionalData = new HashMap<>(); + additionalData.put("path", request.getPath()); + additionalData.put("idInfo", request.getIdInfo()); + + MulticastMessage message = MulticastMessage.builder() + .addAllTokens(fcmTokens) + .setNotification(notification) + .setAndroidConfig(androidConfig) // Applying Android configuration + .setApnsConfig(apnsConfig) // Applying APNs configuration + .putAllData(additionalData) + .build(); + + try { + BatchResponse response = firebaseMessaging.sendMulticast(message); + + + List failedTokens = new ArrayList<>(); + + if (response.getFailureCount() > 0) { + List responses = response.getResponses(); + + List memberIds = AlarmHistoryMapper.getMemberIds(request.getMemberIdAndTokens()); + + for (int i = 0; i < responses.size(); i++) { + if (!responses.get(i).isSuccessful()) { + // Add the failed tokens to the list + failedTokens.add(fcmTokens.get(i)); + } + } + } + + String messageString = String.format("%d messages were sent successfully.", response.getSuccessCount()); + + new MultiResponse(messageString, failedTokens); + + } catch (FirebaseMessagingException e) { + throw ExceptionHandler.handleFirebaseMessagingException(e); + } + } + +} diff --git a/src/main/java/com/moing/backend/global/config/fcm/service/SingleMessageSender.java b/src/main/java/com/moing/backend/global/config/fcm/service/SingleMessageSender.java new file mode 100644 index 00000000..fa069c8e --- /dev/null +++ b/src/main/java/com/moing/backend/global/config/fcm/service/SingleMessageSender.java @@ -0,0 +1,73 @@ +package com.moing.backend.global.config.fcm.service; + +import com.google.firebase.messaging.*; +import com.moing.backend.global.config.fcm.dto.request.SingleRequest; +import com.moing.backend.global.config.fcm.dto.response.SingleResponse; +import com.moing.backend.global.config.fcm.exception.ExceptionHandler; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.retry.annotation.Backoff; +import org.springframework.retry.annotation.Retryable; +import org.springframework.stereotype.Service; + +import javax.transaction.Transactional; +import java.util.HashMap; +import java.util.Map; + +@Service +@Transactional +@RequiredArgsConstructor +@Slf4j +public class SingleMessageSender implements MessageSender { + + private final FirebaseMessaging firebaseMessaging; + + @Override + @Retryable(value = FirebaseMessagingException.class, maxAttempts = 3, backoff = @Backoff(delay = 1000)) + public void send(SingleRequest request){ + Notification notification = Notification.builder() + .setTitle(request.getTitle()) + .setBody(request.getBody()) + .build(); + + // Android Configuration + AndroidConfig androidConfig = AndroidConfig.builder() + .setPriority(AndroidConfig.Priority.HIGH) + .setNotification(AndroidNotification.builder() + .setChannelId("FCM_Channel") + .setTitle(request.getTitle()) + .setBody(request.getBody()) + .build()) + .build(); + + // APNs Configuration + ApnsConfig apnsConfig = ApnsConfig.builder() + .setAps(Aps.builder() + .setCategory("YOUR_CATEGORY") // Replace with your category + .setAlert(ApsAlert.builder() + .setTitle(request.getTitle()) + .setBody(request.getBody()) + .build()) + .build()) + .build(); + + Map additionalData = new HashMap<>(); + additionalData.put("path", request.getPath()); + additionalData.put("idInfo", request.getIdInfo()); + + Message message = Message.builder() + .setToken(request.getRegistrationToken()) + .setNotification(notification) + .setAndroidConfig(androidConfig) // Applying Android configuration + .setApnsConfig(apnsConfig) // Applying APNs configuration + .putAllData(additionalData) + .build(); + + try { + String response = firebaseMessaging.send(message); + new SingleResponse(response); + } catch (FirebaseMessagingException e) { + throw ExceptionHandler.handleFirebaseMessagingException(e); + } + } +} diff --git a/src/main/java/com/moing/backend/global/config/fcm/util/FcmMessageUtil.java b/src/main/java/com/moing/backend/global/config/fcm/util/FcmMessageUtil.java index 39cb3d92..7b375329 100644 --- a/src/main/java/com/moing/backend/global/config/fcm/util/FcmMessageUtil.java +++ b/src/main/java/com/moing/backend/global/config/fcm/util/FcmMessageUtil.java @@ -1,44 +1,44 @@ -package com.moing.backend.global.config.fcm.util; - -import com.moing.backend.domain.history.application.mapper.AlarmHistoryMapper; -import com.moing.backend.domain.history.application.service.SaveMultiAlarmHistoryUseCase; -import com.moing.backend.domain.history.application.service.SaveSingleAlarmHistoryUseCase; -import com.moing.backend.global.config.fcm.dto.event.MultiFcmEvent; -import com.moing.backend.global.config.fcm.dto.event.SingleFcmEvent; -import com.moing.backend.global.config.fcm.dto.request.MultiRequest; -import com.moing.backend.global.config.fcm.dto.request.SingleRequest; -import com.moing.backend.global.config.fcm.service.FcmService; -import lombok.RequiredArgsConstructor; -import org.springframework.context.event.EventListener; -import org.springframework.scheduling.annotation.Async; -import org.springframework.stereotype.Component; - -@Component -@RequiredArgsConstructor -public class FcmMessageUtil { - - private final FcmService fcmService; - private final SaveSingleAlarmHistoryUseCase saveSingleAlarmHistoryUseCase; - private final SaveMultiAlarmHistoryUseCase saveMultiAlarmHistoryUseCase; - - @Async - @EventListener - public void onMultiFcmEvent(MultiFcmEvent event) { - if (event.getIdAndTokensByPush().isPresent() && !event.getIdAndTokensByPush().get().isEmpty()) { - fcmService.sendMultipleDevices(new MultiRequest(event.getIdAndTokensByPush().get(), event.getTitle(), event.getBody(), event.getIdInfo(), event.getName(), event.getAlarmType(), event.getPath())); - } - if (event.getIdAndTokensBySave().isPresent() && !event.getIdAndTokensBySave().get().isEmpty()) { - saveMultiAlarmHistoryUseCase.saveAlarmHistories(AlarmHistoryMapper.getMemberIds(event.getIdAndTokensBySave().get()), event.getIdInfo(), event.getTitle(), event.getBody(), event.getName(), event.getAlarmType(), event.getPath()); - } - } - - @Async - @EventListener - public void onSingleFcmEvent(SingleFcmEvent event) { - if (event.getMember().isFirePush() && !event.getMember().isSignOut()) { //알림 on, 로그아웃 안함 - fcmService.sendSingleDevice(new SingleRequest(event.getMember().getFcmToken(), event.getTitle(), event.getBody(), event.getMember().getMemberId(), event.getIdInfo(), event.getName(), event.getAlarmType(), event.getPath())); - } - saveSingleAlarmHistoryUseCase.saveAlarmHistory(event.getMember().getMemberId(), event.getIdInfo(), event.getTitle(), event.getBody(), event.getName(), event.getAlarmType(), event.getPath()); - } -} - +//package com.moing.backend.global.config.fcm.util; +// +//import com.moing.backend.domain.history.application.mapper.AlarmHistoryMapper; +//import com.moing.backend.domain.history.application.service.SaveMultiAlarmHistoryUseCase; +//import com.moing.backend.domain.history.application.service.SaveSingleAlarmHistoryUseCase; +//import com.moing.backend.global.config.fcm.dto.event.MultiFcmEvent; +//import com.moing.backend.global.config.fcm.dto.event.SingleFcmEvent; +//import com.moing.backend.global.config.fcm.dto.request.MultiRequest; +//import com.moing.backend.global.config.fcm.dto.request.SingleRequest; +//import com.moing.backend.global.config.fcm.service.FcmService; +//import lombok.RequiredArgsConstructor; +//import org.springframework.context.event.EventListener; +//import org.springframework.scheduling.annotation.Async; +//import org.springframework.stereotype.Component; +// +//@Component +//@RequiredArgsConstructor +//public class FcmMessageUtil { +// +// private final FcmService fcmService; +// private final SaveSingleAlarmHistoryUseCase saveSingleAlarmHistoryUseCase; +// private final SaveMultiAlarmHistoryUseCase saveMultiAlarmHistoryUseCase; +// +// @Async +// @EventListener +// public void onMultiFcmEvent(MultiFcmEvent event) { +// if (event.getIdAndTokensByPush().isPresent() && !event.getIdAndTokensByPush().get().isEmpty()) { +// fcmService.sendMultipleDevices(new MultiRequest(event.getIdAndTokensByPush().get(), event.getTitle(), event.getBody(), event.getIdInfo(), event.getName(), event.getAlarmType(), event.getPath())); +// } +// if (event.getIdAndTokensBySave().isPresent() && !event.getIdAndTokensBySave().get().isEmpty()) { +// saveMultiAlarmHistoryUseCase.saveAlarmHistories(AlarmHistoryMapper.getMemberIds(event.getIdAndTokensBySave().get()), event.getIdInfo(), event.getTitle(), event.getBody(), event.getName(), event.getAlarmType(), event.getPath()); +// } +// } +// +// @Async +// @EventListener +// public void onSingleFcmEvent(SingleFcmEvent event) { +// if (event.getMember().isFirePush() && !event.getMember().isSignOut()) { //알림 on, 로그아웃 안함 +// fcmService.sendSingleDevice(new SingleRequest(event.getMember().getFcmToken(), event.getTitle(), event.getBody(), event.getMember().getMemberId(), event.getIdInfo(), event.getName(), event.getAlarmType(), event.getPath())); +// } +// saveSingleAlarmHistoryUseCase.saveAlarmHistory(event.getMember().getMemberId(), event.getIdInfo(), event.getTitle(), event.getBody(), event.getName(), event.getAlarmType(), event.getPath()); +// } +//} +//