From a222d294e121851229e94d0e916aa40d7371c83b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 7 Nov 2023 18:11:16 +0900 Subject: [PATCH 01/45] =?UTF-8?q?refactor:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=EC=9D=98=20=EC=83=9D=EB=85=84?= =?UTF-8?q?=EC=9B=94=EC=9D=BC,=20=EC=9D=B4=EB=A6=84=20=ED=95=84=EB=93=9C?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../oauth/domain/OAuthMemberDetail.java | 9 ------ .../kakao/dto/KakaoMemberDetail.java | 8 +---- .../server/user/domain/Profile.java | 32 ++----------------- .../user/presentation/dto/MyProfileHTTP.java | 6 ---- .../server/user/service/UserService.java | 7 ++-- .../server/user/service/dto/MyProfileDto.java | 6 ---- 6 files changed, 6 insertions(+), 62 deletions(-) diff --git a/src/main/java/coffeemeet/server/oauth/domain/OAuthMemberDetail.java b/src/main/java/coffeemeet/server/oauth/domain/OAuthMemberDetail.java index 53f33c37..5b45262f 100644 --- a/src/main/java/coffeemeet/server/oauth/domain/OAuthMemberDetail.java +++ b/src/main/java/coffeemeet/server/oauth/domain/OAuthMemberDetail.java @@ -3,29 +3,20 @@ import coffeemeet.server.user.domain.OAuthProvider; public record OAuthMemberDetail( - String name, String profileImage, - String birthYear, - String birthDay, String email, OAuthProvider oAuthProvider, String oAuthProviderId ) { public static OAuthMemberDetail of( - String name, String profileImage, - String birthYear, - String birthDay, String email, OAuthProvider oAuthProvider, String oAuthProviderId ) { return new OAuthMemberDetail( - name, profileImage, - birthYear, - birthDay, email, oAuthProvider, oAuthProviderId diff --git a/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberDetail.java b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberDetail.java index 7f644b03..0f12b042 100644 --- a/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberDetail.java +++ b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberDetail.java @@ -13,10 +13,7 @@ public record KakaoMemberDetail( public OAuthMemberDetail toOAuthMemberDetail() { return OAuthMemberDetail.of( - kakaoAccount.name, kakaoAccount.profile.profileImageUrl, - kakaoAccount.birthyear, - kakaoAccount.birthday, kakaoAccount.email, OAuthProvider.KAKAO, String.valueOf(id) @@ -26,10 +23,7 @@ public OAuthMemberDetail toOAuthMemberDetail() { @JsonNaming(SnakeCaseStrategy.class) private record KakaoAccount( Profile profile, - String name, - String email, - String birthyear, - String birthday + String email ) { } diff --git a/src/main/java/coffeemeet/server/user/domain/Profile.java b/src/main/java/coffeemeet/server/user/domain/Profile.java index fd9f5545..11be2840 100644 --- a/src/main/java/coffeemeet/server/user/domain/Profile.java +++ b/src/main/java/coffeemeet/server/user/domain/Profile.java @@ -1,6 +1,5 @@ package coffeemeet.server.user.domain; -import static coffeemeet.server.user.exception.UserErrorCode.INVALID_NAME; import static coffeemeet.server.user.exception.UserErrorCode.INVALID_NICKNAME; import static coffeemeet.server.user.exception.UserErrorCode.INVALID_PROFILE_IMAGE; @@ -9,8 +8,6 @@ import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import jakarta.persistence.Embedded; -import lombok.AccessLevel; -import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.NonNull; @@ -18,17 +15,13 @@ @Getter @Embeddable -@NoArgsConstructor(access = AccessLevel.PROTECTED) +@NoArgsConstructor public class Profile { private static final int NICKNAME_MAX_LENGTH = 20; private static final String INVALID_NICKNAME_MESSAGE = "올바르지 않은 닉네임(%s)입니다."; - private static final String INVALID_NAME_MESSAGE = "올바르지 않은 이름(%s)입니다."; private static final String INVALID_PROFILE_IMAGE_URL_MESSAGE = "올바르지 않은 프로필 사진(%s)입니다."; - @Column(nullable = false) - private String name; - @Column(nullable = false, length = NICKNAME_MAX_LENGTH) private String nickname; @@ -39,26 +32,16 @@ public class Profile { @Column(nullable = false) private String profileImageUrl; - @Embedded - @Column(nullable = false) - private Birth birth; - - @Builder - private Profile( - @NonNull String name, + public Profile( @NonNull String nickname, @NonNull Email email, - @NonNull String profileImageUrl, - @NonNull Birth birth + @NonNull String profileImageUrl ) { validateNickname(nickname); - validateName(name); validateProfileImageUrl(profileImageUrl); - this.name = name; this.nickname = nickname; this.email = email; this.profileImageUrl = profileImageUrl; - this.birth = birth; } public void updateNickname(String newNickname) { @@ -80,15 +63,6 @@ private void validateNickname(String nickname) { } } - private void validateName(String name) { - if (!StringUtils.hasText(name)) { - throw new InvalidInputException( - INVALID_NAME, - String.format(INVALID_NAME_MESSAGE, name) - ); - } - } - private void validateProfileImageUrl(String profileImageUrl) { if (!StringUtils.hasText(profileImageUrl)) { throw new InvalidInputException( diff --git a/src/main/java/coffeemeet/server/user/presentation/dto/MyProfileHTTP.java b/src/main/java/coffeemeet/server/user/presentation/dto/MyProfileHTTP.java index 79577f90..0fd48c83 100644 --- a/src/main/java/coffeemeet/server/user/presentation/dto/MyProfileHTTP.java +++ b/src/main/java/coffeemeet/server/user/presentation/dto/MyProfileHTTP.java @@ -9,12 +9,9 @@ public sealed interface MyProfileHTTP permits MyProfileHTTP.Response { record Response( - String name, String nickname, String email, String profileImageUrl, - String birthYear, - String birthDay, int reportedCount, LocalDateTime sanctionPeriod, Department department, @@ -23,12 +20,9 @@ record Response( public static Response of(MyProfileDto.Response response) { return new Response( - response.name(), response.nickname(), response.email(), response.profileImageUrl(), - response.birthYear(), - response.birthDay(), response.reportedCount(), response.sanctionPeriod(), response.department(), diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index b1aaef5f..455430cf 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -9,7 +9,6 @@ import coffeemeet.server.common.implement.MediaManager; import coffeemeet.server.oauth.domain.OAuthMemberDetail; import coffeemeet.server.oauth.implement.client.OAuthMemberClientComposite; -import coffeemeet.server.user.domain.Birth; import coffeemeet.server.user.domain.Email; import coffeemeet.server.user.domain.Keyword; import coffeemeet.server.user.domain.OAuthInfo; @@ -56,10 +55,8 @@ public AuthTokens signup(String nickname, List keywords, String authCod User user = new User(new OAuthInfo(memberDetail.oAuthProvider(), memberDetail.oAuthProviderId()), - Profile.builder().name(memberDetail.name()).nickname(nickname) - .email(new Email(memberDetail.email())) - .profileImageUrl(profileImage) - .birth(new Birth(memberDetail.birthYear(), memberDetail.birthDay())).build()); + new Profile(nickname, new Email(memberDetail.email()), profileImage) + ); Long userId = userCommand.saveUser(user); User newUser = userQuery.getUserById(userId); diff --git a/src/main/java/coffeemeet/server/user/service/dto/MyProfileDto.java b/src/main/java/coffeemeet/server/user/service/dto/MyProfileDto.java index 338429d8..1fd976e8 100644 --- a/src/main/java/coffeemeet/server/user/service/dto/MyProfileDto.java +++ b/src/main/java/coffeemeet/server/user/service/dto/MyProfileDto.java @@ -9,12 +9,9 @@ public sealed interface MyProfileDto permits MyProfileDto.Response { record Response( - String name, String nickname, String email, String profileImageUrl, - String birthYear, - String birthDay, int reportedCount, LocalDateTime sanctionPeriod, Department department, @@ -23,12 +20,9 @@ record Response( public static Response of(User user, List interests, Department department) { return new Response( - user.getProfile().getName(), user.getProfile().getNickname(), user.getProfile().getEmail().getEmail(), user.getProfile().getProfileImageUrl(), - user.getProfile().getBirth().getBirthYear(), - user.getProfile().getBirth().getBirthDay(), user.getReportInfo().getReportedCount(), user.getReportInfo().getSanctionPeriod(), department, From d39a693694aa312e1a53f0bbd8382509695d2cf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 7 Nov 2023 18:12:49 +0900 Subject: [PATCH 02/45] =?UTF-8?q?test:=20=EB=B3=80=EA=B2=BD=EB=90=9C=20?= =?UTF-8?q?=EC=9C=A0=EC=A0=80=20=ED=94=84=EB=A1=9C=ED=95=84=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=EC=97=90=20=EB=94=B0=EB=9D=BC=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/fixture/dto/MyProfileDtoFixture.java | 2 -- .../common/fixture/dto/OAuthUserInfoDtoFixture.java | 2 -- .../server/common/fixture/entity/UserFixture.java | 9 --------- .../user/presentation/UserControllerTest.java | 3 --- .../server/user/service/UserServiceTest.java | 13 ++----------- 5 files changed, 2 insertions(+), 27 deletions(-) diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/MyProfileDtoFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/MyProfileDtoFixture.java index 37683f08..cc32eddf 100644 --- a/src/test/java/coffeemeet/server/common/fixture/dto/MyProfileDtoFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/dto/MyProfileDtoFixture.java @@ -13,8 +13,6 @@ public class MyProfileDtoFixture { public static MyProfileDto.Response myProfileDtoResponse() { return Instancio.of(MyProfileDto.Response.class) - .generate(field("birthYear"), gen -> gen.ints().range(1000, 9999).asString()) - .generate(field("birthDay"), gen -> gen.ints().range(1000, 9999).asString()) .set(field(Response::interests), keywords()) .set(field("email"), "test123@gmail.com") .set(field("sanctionPeriod"), LocalDateTime.of(1999, 10, 13, 1, 1, 1, 1)) diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/OAuthUserInfoDtoFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/OAuthUserInfoDtoFixture.java index dee2c237..01e1157c 100644 --- a/src/test/java/coffeemeet/server/common/fixture/dto/OAuthUserInfoDtoFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/dto/OAuthUserInfoDtoFixture.java @@ -9,8 +9,6 @@ public class OAuthUserInfoDtoFixture { public static OAuthMemberDetail response() { return Instancio.of(OAuthMemberDetail.class) - .generate(field("birthYear"), gen -> gen.ints().range(1000, 9999).asString()) - .generate(field("birthDay"), gen -> gen.ints().range(1000, 9999).asString()) .set(field("email"), "test123@gmail.com") .create(); } diff --git a/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java b/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java index d3ccada6..6470d120 100644 --- a/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java @@ -2,7 +2,6 @@ import static org.instancio.Select.field; -import coffeemeet.server.user.domain.Birth; import coffeemeet.server.user.domain.Email; import coffeemeet.server.user.domain.Profile; import coffeemeet.server.user.domain.User; @@ -18,16 +17,8 @@ public static User user() { .create(); } - private static Birth birth() { - return Instancio.of(Birth.class) - .generate(field(Birth::getBirthYear), gen -> gen.ints().range(1000, 9999).asString()) - .generate(field(Birth::getBirthDay), gen -> gen.ints().range(1000, 9999).asString()) - .create(); - } - private static Profile profile() { return Instancio.of(Profile.class) - .set(field(Profile::getBirth), birth()) .set(field(Profile::getEmail), new Email("test123@gmail.com")) .generate(field(Profile::getNickname), gen -> gen.string().maxLength(20)) .create(); diff --git a/src/test/java/coffeemeet/server/user/presentation/UserControllerTest.java b/src/test/java/coffeemeet/server/user/presentation/UserControllerTest.java index 4579d1e6..95c28c9b 100644 --- a/src/test/java/coffeemeet/server/user/presentation/UserControllerTest.java +++ b/src/test/java/coffeemeet/server/user/presentation/UserControllerTest.java @@ -181,13 +181,10 @@ void findMyProfileTest() throws Exception { headerWithName("Authorization").description("토큰") ), responseFields( - fieldWithPath("name").type(JsonFieldType.STRING).description("이름"), fieldWithPath("nickname").type(JsonFieldType.STRING).description("닉네임"), fieldWithPath("email").type(JsonFieldType.STRING).description("이메일"), fieldWithPath("profileImageUrl").type(JsonFieldType.STRING) .description("프로필 사진 url"), - fieldWithPath("birthYear").type(JsonFieldType.STRING).description("생일년도"), - fieldWithPath("birthDay").type(JsonFieldType.STRING).description("생일월일"), fieldWithPath("reportedCount").type(JsonFieldType.NUMBER).description("신고 횟수"), fieldWithPath("sanctionPeriod").type(JsonFieldType.STRING).description("제재 기간"), fieldWithPath("department").type(JsonFieldType.STRING).description("부서"), diff --git a/src/test/java/coffeemeet/server/user/service/UserServiceTest.java b/src/test/java/coffeemeet/server/user/service/UserServiceTest.java index fe468fe6..1254c56e 100644 --- a/src/test/java/coffeemeet/server/user/service/UserServiceTest.java +++ b/src/test/java/coffeemeet/server/user/service/UserServiceTest.java @@ -27,7 +27,6 @@ import coffeemeet.server.common.implement.MediaManager; import coffeemeet.server.oauth.domain.OAuthMemberDetail; import coffeemeet.server.oauth.implement.client.OAuthMemberClientComposite; -import coffeemeet.server.user.domain.Birth; import coffeemeet.server.user.domain.Email; import coffeemeet.server.user.domain.Keyword; import coffeemeet.server.user.domain.OAuthInfo; @@ -173,12 +172,9 @@ void findMyProfileTest() { // then assertAll( - () -> assertThat(result.name()).isEqualTo(response.name()), () -> assertThat(result.nickname()).isEqualTo(response.nickname()), () -> assertThat(result.email()).isEqualTo(response.email()), () -> assertThat(result.profileImageUrl()).isEqualTo(response.profileImageUrl()), - () -> assertThat(result.birthYear()).isEqualTo(response.birthYear()), - () -> assertThat(result.birthDay()).isEqualTo(response.birthDay()), () -> assertThat(result.department()).isEqualTo(response.department()), () -> assertThat(result.interests()).isEqualTo(response.interests()) ); @@ -231,13 +227,8 @@ void updateProfileImage() throws IOException { @Test void updateProfileInfo() { // given - User user = new User(new OAuthInfo(KAKAO, "123"), Profile.builder() - .nickname("닉네임") - .name("이름") - .birth(new Birth("2001", "1018")) - .profileImageUrl("http://imageUrl") - .email(new Email("test123@gmail.com")) - .build()); + User user = new User(new OAuthInfo(KAKAO, "123"), + new Profile("닉네임", new Email("test123@gmail.com"), "http://imageUrl")); String newNickname = "새닉네임"; ArrayList newKeywords = new ArrayList<>(Arrays.asList(COOK, GAME)); From 2101400cb9aeb7d61d0c81ab656766e83cb599b7 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 01:52:34 +0900 Subject: [PATCH 03/45] =?UTF-8?q?refactor:=20aws=20config=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/common/config/AWSConfig.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/coffeemeet/server/common/config/AWSConfig.java b/src/main/java/coffeemeet/server/common/config/AWSConfig.java index ce6d6fde..9445dad0 100644 --- a/src/main/java/coffeemeet/server/common/config/AWSConfig.java +++ b/src/main/java/coffeemeet/server/common/config/AWSConfig.java @@ -1,5 +1,6 @@ package coffeemeet.server.common.config; +import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.AWSStaticCredentialsProvider; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.s3.AmazonS3; @@ -25,12 +26,16 @@ public AWSConfig( } @Bean - public AmazonS3 amazonS3Client() { - BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey); + public AWSCredentials awsCredentials() { + return new BasicAWSCredentials(accessKey, secretKey); + } + + @Bean + public AmazonS3 amazonS3Client(AWSCredentials awsCredentials) { return AmazonS3ClientBuilder .standard() .withRegion(region) - .withCredentials(new AWSStaticCredentialsProvider(credentials)) + .withCredentials(new AWSStaticCredentialsProvider(awsCredentials)) .build(); } From c91291abf79327f3cb7f392abb0207c4121c3aa2 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 02:42:13 +0900 Subject: [PATCH 04/45] =?UTF-8?q?chore:=20=EC=9D=98=EC=A1=B4=EC=84=B1=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20AWS=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=EC=84=B1=20=EC=B5=9C=EC=86=8C=ED=95=9C=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e232770e..c1d7b7a5 100644 --- a/build.gradle +++ b/build.gradle @@ -71,7 +71,8 @@ dependencies { swaggerUI 'org.webjars:swagger-ui:4.11.1' /* Cloud */ - implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' + implementation 'com.amazonaws:aws-java-sdk-s3:1.12.581' + implementation 'com.google.firebase:firebase-admin:9.1.1' /* WebSocket */ implementation 'org.springframework.boot:spring-boot-starter-websocket' From 8ae8b4c86d367cc57de2b7c53f644e80c9ae9537 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 02:47:21 +0900 Subject: [PATCH 05/45] =?UTF-8?q?chore:=20firebase=20=ED=82=A4=20=ED=8C=A8?= =?UTF-8?q?=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 9bb9559e..6f4dbad3 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -61,3 +61,6 @@ cloud: auto: false stack: auto: false + firebase: + key-path: + ${CLOUD_FIREBASE_KEY_PATH} From be0825f07b73f12a768a2299379d10dd22f3663a Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 02:52:10 +0900 Subject: [PATCH 06/45] =?UTF-8?q?feat:=20=ED=86=A0=ED=81=B0=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EB=B0=8F=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/coffeemeet/server/user/domain/User.java | 11 +++++++++-- .../coffeemeet/server/user/implement/UserCommand.java | 7 +++++++ .../server/user/presentation/UserController.java | 11 +++++++++++ .../coffeemeet/server/user/service/UserService.java | 4 ++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/domain/User.java b/src/main/java/coffeemeet/server/user/domain/User.java index c92517e9..e5d693fc 100644 --- a/src/main/java/coffeemeet/server/user/domain/User.java +++ b/src/main/java/coffeemeet/server/user/domain/User.java @@ -44,6 +44,9 @@ public class User extends AdvancedBaseEntity { @Column(nullable = false) private ReportInfo reportInfo; + @Embedded + private NotificationInfo notificationInfo; + @Column(nullable = false) private boolean isDeleted; @@ -57,12 +60,16 @@ public User( this.isDeleted = false; } - public void updateProfileImageUrl(String newProfileImageUrl) { + public void updateProfileImageUrl(@NonNull String newProfileImageUrl) { this.profile.updateProfileImageUrl(newProfileImageUrl); } - public void updateNickname(String newNickname) { + public void updateNickname(@NonNull String newNickname) { this.profile.updateNickname(newNickname); } + public void updateNotificationInfo(@NonNull NotificationInfo newNotificationInfo) { + this.notificationInfo = newNotificationInfo; + } + } diff --git a/src/main/java/coffeemeet/server/user/implement/UserCommand.java b/src/main/java/coffeemeet/server/user/implement/UserCommand.java index 173f0d0c..4cb00812 100644 --- a/src/main/java/coffeemeet/server/user/implement/UserCommand.java +++ b/src/main/java/coffeemeet/server/user/implement/UserCommand.java @@ -1,8 +1,10 @@ package coffeemeet.server.user.implement; +import coffeemeet.server.user.domain.NotificationInfo; import coffeemeet.server.user.domain.User; import coffeemeet.server.user.infrastructure.InterestRepository; import coffeemeet.server.user.infrastructure.UserRepository; +import java.time.LocalDateTime; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @@ -34,4 +36,9 @@ public void updateUserInfo(User user, String nickname) { user.updateNickname(nickname); } + public void registerOrUpdateNotificationToken(Long userId, String token) { + User user = userQuery.getUserById(userId); + user.updateNotificationInfo(new NotificationInfo(token, LocalDateTime.now())); + } + } diff --git a/src/main/java/coffeemeet/server/user/presentation/UserController.java b/src/main/java/coffeemeet/server/user/presentation/UserController.java index 428f0d7a..b8d77713 100644 --- a/src/main/java/coffeemeet/server/user/presentation/UserController.java +++ b/src/main/java/coffeemeet/server/user/presentation/UserController.java @@ -3,6 +3,7 @@ import coffeemeet.server.auth.domain.AuthTokens; import coffeemeet.server.common.annotation.Login; import coffeemeet.server.common.domain.AuthInfo; +import coffeemeet.server.common.presentation.NotificationTokenHTTP; import coffeemeet.server.common.util.FileUtils; import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.presentation.dto.MyProfileHTTP; @@ -21,6 +22,7 @@ import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -84,4 +86,13 @@ public ResponseEntity checkDuplicatedNickname(@RequestParam @NotBlank Stri return ResponseEntity.ok().build(); } + @PutMapping("/notification/token") + public ResponseEntity registerOrUpdateNotificationToken( + @Login AuthInfo authInfo, + @RequestBody NotificationTokenHTTP.Request request + ) { + userService.registerOrUpdateNotificationToken(authInfo.userId(), request.token()); + return ResponseEntity.ok().build(); + } + } diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index b1aaef5f..2fc29bd3 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -131,4 +131,8 @@ private void deleteCurrentProfileImage(String profileImageUrl) { mediaManager.delete(currentKey); } + public void registerOrUpdateNotificationToken(Long useId, String token) { + userCommand.registerOrUpdateNotificationToken(useId, token); + } + } From 7911433f74adc56904247eb17208a956d5f378e4 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 02:56:52 +0900 Subject: [PATCH 07/45] =?UTF-8?q?feat:=20=ED=8C=8C=EC=9D=B4=EC=96=B4?= =?UTF-8?q?=EB=B2=A0=EC=9D=B4=EC=8A=A4=20=EC=84=A4=EC=A0=95=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/common/config/FirebaseConfig.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/main/java/coffeemeet/server/common/config/FirebaseConfig.java diff --git a/src/main/java/coffeemeet/server/common/config/FirebaseConfig.java b/src/main/java/coffeemeet/server/common/config/FirebaseConfig.java new file mode 100644 index 00000000..f5ede6ca --- /dev/null +++ b/src/main/java/coffeemeet/server/common/config/FirebaseConfig.java @@ -0,0 +1,37 @@ +package coffeemeet.server.common.config; + +import com.google.auth.oauth2.GoogleCredentials; +import com.google.firebase.FirebaseApp; +import com.google.firebase.FirebaseOptions; +import com.google.firebase.messaging.FirebaseMessaging; +import java.io.IOException; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; + +@Configuration +public class FirebaseConfig { + + private final String filename; + + public FirebaseConfig(@Value("${cloud.firebase.key-path}") String filename) { + this.filename = filename; + } + + @Bean + FirebaseApp firebaseApp() throws IOException { + ClassPathResource resource = new ClassPathResource(filename); + + FirebaseOptions options = FirebaseOptions.builder() + .setCredentials(GoogleCredentials.fromStream(resource.getInputStream())).build(); + + return FirebaseApp.initializeApp(options); + } + + @Bean + FirebaseMessaging firebaseMessaging(FirebaseApp firebaseApp) { + return FirebaseMessaging.getInstance(firebaseApp); + } + +} From 11bec2934ddbeaef8183d6d6fefef8e93c6d601e Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 03:14:20 +0900 Subject: [PATCH 08/45] =?UTF-8?q?style:=20=ED=8C=A8=ED=82=A4=EC=A7=80=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/user/presentation/UserController.java | 2 +- .../presentation/dto/NotificationTokenHTTP.java | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 src/main/java/coffeemeet/server/user/presentation/dto/NotificationTokenHTTP.java diff --git a/src/main/java/coffeemeet/server/user/presentation/UserController.java b/src/main/java/coffeemeet/server/user/presentation/UserController.java index b8d77713..fd9c4798 100644 --- a/src/main/java/coffeemeet/server/user/presentation/UserController.java +++ b/src/main/java/coffeemeet/server/user/presentation/UserController.java @@ -3,7 +3,7 @@ import coffeemeet.server.auth.domain.AuthTokens; import coffeemeet.server.common.annotation.Login; import coffeemeet.server.common.domain.AuthInfo; -import coffeemeet.server.common.presentation.NotificationTokenHTTP; +import coffeemeet.server.user.presentation.dto.NotificationTokenHTTP; import coffeemeet.server.common.util.FileUtils; import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.presentation.dto.MyProfileHTTP; diff --git a/src/main/java/coffeemeet/server/user/presentation/dto/NotificationTokenHTTP.java b/src/main/java/coffeemeet/server/user/presentation/dto/NotificationTokenHTTP.java new file mode 100644 index 00000000..7f764e5d --- /dev/null +++ b/src/main/java/coffeemeet/server/user/presentation/dto/NotificationTokenHTTP.java @@ -0,0 +1,15 @@ +package coffeemeet.server.user.presentation.dto; + +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotNull; + +public sealed interface NotificationTokenHTTP permits NotificationTokenHTTP.Request { + + record Request( + @Email @NotNull + String token + ) implements NotificationTokenHTTP { + + } + +} From a3db7aa9ccd373955ddf05a9c38de3b46c6a6e19 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 03:15:11 +0900 Subject: [PATCH 09/45] =?UTF-8?q?feat:=20=EC=95=8C=EB=A6=BC=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/user/domain/NotificationInfo.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/main/java/coffeemeet/server/user/domain/NotificationInfo.java diff --git a/src/main/java/coffeemeet/server/user/domain/NotificationInfo.java b/src/main/java/coffeemeet/server/user/domain/NotificationInfo.java new file mode 100644 index 00000000..fb4d9873 --- /dev/null +++ b/src/main/java/coffeemeet/server/user/domain/NotificationInfo.java @@ -0,0 +1,26 @@ +package coffeemeet.server.user.domain; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import java.time.LocalDateTime; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Embeddable +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class NotificationInfo { + + @Column(name = "firebase_notification_token") + private String token; + + @Column(name = "created_firebase_notification_token_at") + private LocalDateTime createdTokenAt; + + public NotificationInfo(String token, LocalDateTime createdTokenAt) { + this.token = token; + this.createdTokenAt = createdTokenAt; + } + +} From a1c5b81e80cdd3add96f0431486a737510ea9565 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 03:19:29 +0900 Subject: [PATCH 10/45] =?UTF-8?q?test:=20private=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../certification/service/cq/CertificationCommandTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/coffeemeet/server/certification/service/cq/CertificationCommandTest.java b/src/test/java/coffeemeet/server/certification/service/cq/CertificationCommandTest.java index b06ddd28..f7d9d23b 100644 --- a/src/test/java/coffeemeet/server/certification/service/cq/CertificationCommandTest.java +++ b/src/test/java/coffeemeet/server/certification/service/cq/CertificationCommandTest.java @@ -32,7 +32,7 @@ class CertificationCommandTest { @Mock - Consumer consumer; + private Consumer consumer; @InjectMocks private CertificationCommand certificationCommand; @Mock From 1e17420b2752b1ad50e4a8f3c34c08a1c0461f64 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 06:06:18 +0900 Subject: [PATCH 11/45] =?UTF-8?q?fix:=20return=20=EA=B0=92=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 --- .../certification/exception/CertificationErrorCode.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/exception/CertificationErrorCode.java b/src/main/java/coffeemeet/server/certification/exception/CertificationErrorCode.java index 5d215835..11000155 100644 --- a/src/main/java/coffeemeet/server/certification/exception/CertificationErrorCode.java +++ b/src/main/java/coffeemeet/server/certification/exception/CertificationErrorCode.java @@ -17,12 +17,12 @@ public enum CertificationErrorCode implements ErrorCode { @Override public String code() { - return null; + return errorCode; } @Override public String message() { - return null; + return message; } } From 5c3c6b78302b0ff6997fe4362750b49717086f69 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 06:47:48 +0900 Subject: [PATCH 12/45] =?UTF-8?q?feat:=20=EC=95=8C=EB=A6=BC=20=EA=B1=B0?= =?UTF-8?q?=EC=A0=88=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/user/domain/NotificationInfo.java | 7 +++++++ .../coffeemeet/server/user/implement/UserCommand.java | 5 +++++ .../server/user/presentation/UserController.java | 8 ++++++++ .../java/coffeemeet/server/user/service/UserService.java | 4 ++++ 4 files changed, 24 insertions(+) diff --git a/src/main/java/coffeemeet/server/user/domain/NotificationInfo.java b/src/main/java/coffeemeet/server/user/domain/NotificationInfo.java index fb4d9873..86f1869a 100644 --- a/src/main/java/coffeemeet/server/user/domain/NotificationInfo.java +++ b/src/main/java/coffeemeet/server/user/domain/NotificationInfo.java @@ -15,6 +15,9 @@ public class NotificationInfo { @Column(name = "firebase_notification_token") private String token; + @Column(name = "is_subscribed_to_notifications") + private boolean isSubscribedToNotification; + @Column(name = "created_firebase_notification_token_at") private LocalDateTime createdTokenAt; @@ -23,4 +26,8 @@ public NotificationInfo(String token, LocalDateTime createdTokenAt) { this.createdTokenAt = createdTokenAt; } + public NotificationInfo(boolean isSubscribedToNotification) { + this.isSubscribedToNotification = isSubscribedToNotification; + } + } diff --git a/src/main/java/coffeemeet/server/user/implement/UserCommand.java b/src/main/java/coffeemeet/server/user/implement/UserCommand.java index 4cb00812..bb218796 100644 --- a/src/main/java/coffeemeet/server/user/implement/UserCommand.java +++ b/src/main/java/coffeemeet/server/user/implement/UserCommand.java @@ -41,4 +41,9 @@ public void registerOrUpdateNotificationToken(Long userId, String token) { user.updateNotificationInfo(new NotificationInfo(token, LocalDateTime.now())); } + public void unsubscribeNotification(Long userId) { + User user = userQuery.getUserById(userId); + user.updateNotificationInfo(new NotificationInfo(false)); + } + } diff --git a/src/main/java/coffeemeet/server/user/presentation/UserController.java b/src/main/java/coffeemeet/server/user/presentation/UserController.java index fd9c4798..16e885f7 100644 --- a/src/main/java/coffeemeet/server/user/presentation/UserController.java +++ b/src/main/java/coffeemeet/server/user/presentation/UserController.java @@ -95,4 +95,12 @@ public ResponseEntity registerOrUpdateNotificationToken( return ResponseEntity.ok().build(); } + @PutMapping("/notification/unsubscription") + public ResponseEntity unsubscribeNotification( + @Login AuthInfo authInfo + ) { + userService.unsubscribeNotification(authInfo.userId()); + return ResponseEntity.ok().build(); + } + } diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 2fc29bd3..a6ca4d39 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -135,4 +135,8 @@ public void registerOrUpdateNotificationToken(Long useId, String token) { userCommand.registerOrUpdateNotificationToken(useId, token); } + public void unsubscribeNotification(Long userId) { + userCommand.unsubscribeNotification(userId); + } + } From 4c891299ecded62660d71bf3251b599f2880f9e8 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 06:49:10 +0900 Subject: [PATCH 13/45] =?UTF-8?q?feat:=20=EC=97=90=EB=9F=AC,=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=EC=BD=94=EB=93=9C,=20=ED=95=B8=EB=93=A4=EB=9F=AC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/common/execption/GlobalErrorCode.java | 6 ++++-- .../InvalidNotificationTokenException.java | 15 +++++++++++++++ .../execption/NotificationFailException.java | 15 +++++++++++++++ .../advice/GlobalExceptionHandler.java | 8 ++++++++ 4 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 src/main/java/coffeemeet/server/common/execption/InvalidNotificationTokenException.java create mode 100644 src/main/java/coffeemeet/server/common/execption/NotificationFailException.java diff --git a/src/main/java/coffeemeet/server/common/execption/GlobalErrorCode.java b/src/main/java/coffeemeet/server/common/execption/GlobalErrorCode.java index 66c1b186..3e1a8146 100644 --- a/src/main/java/coffeemeet/server/common/execption/GlobalErrorCode.java +++ b/src/main/java/coffeemeet/server/common/execption/GlobalErrorCode.java @@ -8,8 +8,10 @@ public enum GlobalErrorCode implements ErrorCode { VALIDATION_ERROR("G000", "유효하지 않은 입력입니다."), - INVALID_S3_URL("G004", "유효하지 않은 s3 url 입니다."), - STOMP_ACCESSOR_NOT_FOUND("G004", "웹소켓 연결을 할 수 없습니다."), + INVALID_FCM_TOKEN("G001", "유효하지 않은 FCM토큰입니다."), + PUSH_NOTIFICATION_SEND_FAILURE("G002", "푸시 알림 전송에 실패했습니다."), + INVALID_S3_URL("G004", "유효하지 않은 s3 URL 입니다."), + STOMP_ACCESSOR_NOT_FOUND("G005", "웹소켓 연결을 할 수 없습니다."), INTERNAL_SERVER_ERROR("G050", "예상치 못한 오류입니다."); private final String code; diff --git a/src/main/java/coffeemeet/server/common/execption/InvalidNotificationTokenException.java b/src/main/java/coffeemeet/server/common/execption/InvalidNotificationTokenException.java new file mode 100644 index 00000000..3b1ec802 --- /dev/null +++ b/src/main/java/coffeemeet/server/common/execption/InvalidNotificationTokenException.java @@ -0,0 +1,15 @@ +package coffeemeet.server.common.execption; + +import lombok.Getter; + +@Getter +public class InvalidNotificationTokenException extends CoffeeMeetException { + + private final ErrorCode errorCode; + + public InvalidNotificationTokenException(ErrorCode errorCode, String message) { + super(message); + this.errorCode = errorCode; + } + +} diff --git a/src/main/java/coffeemeet/server/common/execption/NotificationFailException.java b/src/main/java/coffeemeet/server/common/execption/NotificationFailException.java new file mode 100644 index 00000000..2945f5eb --- /dev/null +++ b/src/main/java/coffeemeet/server/common/execption/NotificationFailException.java @@ -0,0 +1,15 @@ +package coffeemeet.server.common.execption; + +import lombok.Getter; + +@Getter +public class NotificationFailException extends CoffeeMeetException { + + private final ErrorCode errorCode; + + public NotificationFailException(ErrorCode errorCode, String message) { + super(message); + this.errorCode = errorCode; + } + +} diff --git a/src/main/java/coffeemeet/server/common/presentation/advice/GlobalExceptionHandler.java b/src/main/java/coffeemeet/server/common/presentation/advice/GlobalExceptionHandler.java index 68988ce5..aa861ae7 100644 --- a/src/main/java/coffeemeet/server/common/presentation/advice/GlobalExceptionHandler.java +++ b/src/main/java/coffeemeet/server/common/presentation/advice/GlobalExceptionHandler.java @@ -4,6 +4,7 @@ import coffeemeet.server.common.execption.GlobalErrorCode; import coffeemeet.server.common.execption.InvalidAuthException; import coffeemeet.server.common.execption.InvalidInputException; +import coffeemeet.server.common.execption.InvalidNotificationTokenException; import coffeemeet.server.common.execption.MissMatchException; import coffeemeet.server.common.execption.NotFoundException; import lombok.RequiredArgsConstructor; @@ -50,6 +51,13 @@ public ResponseEntity handleException(InvalidInputException excep .body(ErrorResponse.of(exception.getErrorCode())); } + @ExceptionHandler(InvalidNotificationTokenException.class) + public ResponseEntity handleException(InvalidNotificationTokenException exception) { + log.info(exception.getMessage(), exception); + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(ErrorResponse.of(exception.getErrorCode())); + } + @ExceptionHandler(MissMatchException.class) public ResponseEntity handleException(MissMatchException exception) { log.info(exception.getMessage(), exception); From 4ed859a253613479a63cad9c76fa3e129347b061 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 17:04:19 +0900 Subject: [PATCH 14/45] =?UTF-8?q?test:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=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 --- .../certification/presentation/CertificationControllerTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/java/coffeemeet/server/certification/presentation/CertificationControllerTest.java b/src/test/java/coffeemeet/server/certification/presentation/CertificationControllerTest.java index b78d6d79..76a5b382 100644 --- a/src/test/java/coffeemeet/server/certification/presentation/CertificationControllerTest.java +++ b/src/test/java/coffeemeet/server/certification/presentation/CertificationControllerTest.java @@ -51,8 +51,6 @@ void setUp() { RefreshToken refreshToken = refreshToken(); given(refreshTokenQuery.getRefreshToken(anyLong())).willReturn(refreshToken); given(jwtTokenProvider.extractUserId(TOKEN)).willReturn(userId); - willDoNothing().given(certificationService) - .registerCertification(anyLong(), any(), any(), any(), any()); } @Test From 3234d2a2381efb17bbca999c32d5a3aac25cb7ae Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 17:04:46 +0900 Subject: [PATCH 15/45] =?UTF-8?q?test:=20=EC=9C=A0=EC=A0=80=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=20=ED=86=A0=ED=81=B0=20=EB=93=B1=EB=A1=9D=20=EB=B0=8F?= =?UTF-8?q?=20=EC=95=8C=EB=A6=BC=20=EA=B1=B0=EB=B6=80=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/fixture/entity/UserFixture.java | 9 +++ .../user/presentation/UserControllerTest.java | 63 +++++++++++++++---- .../server/user/service/UserServiceTest.java | 28 +++++++++ 3 files changed, 89 insertions(+), 11 deletions(-) diff --git a/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java b/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java index d3ccada6..84ee8ff4 100644 --- a/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java @@ -6,6 +6,7 @@ import coffeemeet.server.user.domain.Email; import coffeemeet.server.user.domain.Profile; import coffeemeet.server.user.domain.User; +import coffeemeet.server.user.presentation.dto.NotificationTokenHTTP; import org.instancio.Instancio; public class UserFixture { @@ -33,4 +34,12 @@ private static Profile profile() { .create(); } + public static NotificationTokenHTTP.Request notificationTokenHTTPRequest() { + return Instancio.create(NotificationTokenHTTP.Request.class); + } + + public static String token() { + return Instancio.create(String.class); + } + } diff --git a/src/test/java/coffeemeet/server/user/presentation/UserControllerTest.java b/src/test/java/coffeemeet/server/user/presentation/UserControllerTest.java index 4579d1e6..c250dbbb 100644 --- a/src/test/java/coffeemeet/server/user/presentation/UserControllerTest.java +++ b/src/test/java/coffeemeet/server/user/presentation/UserControllerTest.java @@ -1,8 +1,10 @@ package coffeemeet.server.user.presentation; +import static coffeemeet.server.common.fixture.entity.UserFixture.notificationTokenHTTPRequest; import static coffeemeet.server.common.fixture.entity.UserFixture.user; import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.resourceDetails; +import static org.apache.http.HttpHeaders.AUTHORIZATION; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.BDDMockito.given; @@ -13,6 +15,7 @@ import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.multipart; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.put; import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest; import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse; import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; @@ -37,12 +40,14 @@ import coffeemeet.server.common.fixture.dto.UserProfileDtoFixture; import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.domain.User; +import coffeemeet.server.user.presentation.dto.NotificationTokenHTTP; import coffeemeet.server.user.presentation.dto.SignupHTTP; import coffeemeet.server.user.presentation.dto.UpdateProfileHTTP.Request; import coffeemeet.server.user.service.UserService; import coffeemeet.server.user.service.dto.MyProfileDto.Response; import coffeemeet.server.user.service.dto.UserProfileDto; import com.epages.restdocs.apispec.Schema; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -57,6 +62,12 @@ class UserControllerTest extends ControllerTestConfig { @MockBean private UserService userService; + @BeforeEach + void setUp() { + RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); + given(refreshTokenQuery.getRefreshToken(anyLong())).willReturn(refreshToken); + } + @Test @DisplayName("회원가입을 할 수 있다.") void signupTest() throws Exception { @@ -162,10 +173,8 @@ void findUserProfileTest() throws Exception { void findMyProfileTest() throws Exception { // given Long userId = 1L; - RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); Response response = MyProfileDtoFixture.myProfileDtoResponse(); - given(refreshTokenQuery.getRefreshToken(anyLong())).willReturn(refreshToken); given(jwtTokenProvider.extractUserId(TOKEN)).willReturn(userId); given(userService.findMyProfile(anyLong())).willReturn(response); @@ -203,9 +212,7 @@ void findMyProfileTest() throws Exception { void updateProfileImageTest() throws Exception { // given Long userId = 1L; - RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); - given(refreshTokenQuery.getRefreshToken(anyLong())).willReturn(refreshToken); given(jwtTokenProvider.extractUserId(TOKEN)).willReturn(userId); MockMultipartFile file = new MockMultipartFile("image", @@ -239,14 +246,12 @@ void updateProfileInfoTest() throws Exception { // given Long userId = 1L; Request request = UpdateProfileDtoFixture.updateProfileDtoRequest(); - RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); - given(refreshTokenQuery.getRefreshToken(anyLong())).willReturn(refreshToken); given(jwtTokenProvider.extractUserId(TOKEN)).willReturn(userId); willDoNothing().given( userService).updateProfileInfo(any(), any(), any()); - // when, given + // when, then mockMvc.perform(patch("/api/v1/users/me") .header("Authorization", TOKEN) .contentType(MediaType.APPLICATION_JSON) @@ -274,11 +279,8 @@ void checkNicknameDuplicationTest() throws Exception { // given User user = user(); String nickname = user.getProfile().getNickname(); - RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); - - given(refreshTokenQuery.getRefreshToken(anyLong())).willReturn(refreshToken); - // when, given + // when, then mockMvc.perform(get("/api/v1/users/duplicate") .param("nickname", nickname) ) @@ -292,4 +294,43 @@ void checkNicknameDuplicationTest() throws Exception { ); } + @Test + @DisplayName("FCM 토큰을 등록하거나 업데이트할 수 있다.") + void registerOrUpdateNotificationTokenTest() throws Exception { + // given + NotificationTokenHTTP.Request request = notificationTokenHTTPRequest(); + + // when, then + mockMvc.perform(put("/api/v1/users/notification/token") + .header(AUTHORIZATION, TOKEN) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request)) + ).andDo(document("register-or-update-token", + resourceDetails().tag("사용자").description("토큰 등록 및 업데이트"), + requestHeaders( + headerWithName(AUTHORIZATION).description("토큰") + ), + requestFields( + fieldWithPath("token").type(JsonFieldType.STRING).description("토큰") + ) + )) + .andExpect(status().isOk()); + } + + @Test + @DisplayName("푸시 알림을 거부할 수 있다.") + void unsubscribeNotificationTest() throws Exception { + // given, when, then + mockMvc.perform(put("/api/v1/users/notification/unsubscription") + .header(AUTHORIZATION, TOKEN) + .contentType(MediaType.APPLICATION_JSON) + ).andDo(document("unsubscribe-notification", + resourceDetails().tag("사용자").description("알림 거부"), + requestHeaders( + headerWithName(AUTHORIZATION).description("토큰") + ) + )) + .andExpect(status().isOk()); + } + } diff --git a/src/test/java/coffeemeet/server/user/service/UserServiceTest.java b/src/test/java/coffeemeet/server/user/service/UserServiceTest.java index fe468fe6..b330f21b 100644 --- a/src/test/java/coffeemeet/server/user/service/UserServiceTest.java +++ b/src/test/java/coffeemeet/server/user/service/UserServiceTest.java @@ -14,7 +14,9 @@ import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; import static org.mockito.BDDMockito.willDoNothing; +import static org.mockito.Mockito.only; import static org.mockito.Mockito.verify; import coffeemeet.server.auth.domain.AuthTokens; @@ -281,4 +283,30 @@ void checkDuplicatedNickname() { .doesNotThrowAnyException(); } + @Test + @DisplayName("푸시 알림 토큰을 등록 및 업데이트 할 수 있다.") + void registerOrUpdateNotificationTokenTest() { + // given + willDoNothing().given(userCommand).registerOrUpdateNotificationToken(any(), any()); + + // when + userService.registerOrUpdateNotificationToken(any(),any()); + + // then + then(userCommand).should(only()).registerOrUpdateNotificationToken(any(), any()); + } + + @Test + @DisplayName("푸시 알림을 거부할 수 있다.") + void unsubscribeNotificationTest() { + // given + willDoNothing().given(userCommand).unsubscribeNotification(any()); + + // when + userService.unsubscribeNotification(any()); + + // then + then(userCommand).should(only()).unsubscribeNotification(any()); + } + } From d4f8ed8426429259171c37b3d9b0e13ebb54ade0 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 17:07:40 +0900 Subject: [PATCH 16/45] =?UTF-8?q?test:=20=EC=95=8C=EB=A6=BC=20=ED=94=BD?= =?UTF-8?q?=EC=8A=A4=EC=B2=98=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/fixture/entity/UserFixture.java | 34 ++++++++++++++----- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java b/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java index 84ee8ff4..f5fbc5a4 100644 --- a/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java @@ -1,22 +1,22 @@ package coffeemeet.server.common.fixture.entity; +import static java.time.LocalDateTime.now; import static org.instancio.Select.field; import coffeemeet.server.user.domain.Birth; import coffeemeet.server.user.domain.Email; +import coffeemeet.server.user.domain.NotificationInfo; import coffeemeet.server.user.domain.Profile; import coffeemeet.server.user.domain.User; import coffeemeet.server.user.presentation.dto.NotificationTokenHTTP; +import java.util.Set; import org.instancio.Instancio; public class UserFixture { public static User user() { - return Instancio.of(User.class) - .set(field(User::getProfile), profile()) - .ignore(field(User::isDeleted)) - .ignore(field(User::getChattingRoom)) - .create(); + return Instancio.of(User.class).set(field(User::getProfile), profile()) + .ignore(field(User::isDeleted)).ignore(field(User::getChattingRoom)).create(); } private static Birth birth() { @@ -27,11 +27,9 @@ private static Birth birth() { } private static Profile profile() { - return Instancio.of(Profile.class) - .set(field(Profile::getBirth), birth()) + return Instancio.of(Profile.class).set(field(Profile::getBirth), birth()) .set(field(Profile::getEmail), new Email("test123@gmail.com")) - .generate(field(Profile::getNickname), gen -> gen.string().maxLength(20)) - .create(); + .generate(field(Profile::getNickname), gen -> gen.string().maxLength(20)).create(); } public static NotificationTokenHTTP.Request notificationTokenHTTPRequest() { @@ -42,4 +40,22 @@ public static String token() { return Instancio.create(String.class); } + public static NotificationInfo notificationInfo() { + return Instancio.of(NotificationInfo.class) + .set(field(NotificationInfo::isSubscribedToNotification), true) + .generate(field(NotificationInfo::getCreatedTokenAt), + gen -> gen.temporal().localDateTime().range(now().minusMonths(2), now())).create(); + } + + public static Set notificationInfos() { + return Instancio.ofSet(NotificationInfo.class) + .set(field(NotificationInfo::isSubscribedToNotification), true) + .generate(field(NotificationInfo::getCreatedTokenAt), + gen -> gen.temporal().localDateTime().range(now().minusMonths(2), now())).create(); + } + + public static String content() { + return Instancio.create(String.class); + } + } From 384dd1e2d4280887d0d133b319f5d7cf5767af74 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 17:08:07 +0900 Subject: [PATCH 17/45] =?UTF-8?q?test:=20=EC=9C=A0=EC=A0=80=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=20=ED=86=A0=ED=81=B0=20=EB=93=B1=EB=A1=9D=20=EB=B0=8F?= =?UTF-8?q?=20=EC=95=8C=EB=A6=BC=20=EA=B1=B0=EB=B6=80=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/implement/UserCommandTest.java | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/test/java/coffeemeet/server/user/implement/UserCommandTest.java diff --git a/src/test/java/coffeemeet/server/user/implement/UserCommandTest.java b/src/test/java/coffeemeet/server/user/implement/UserCommandTest.java new file mode 100644 index 00000000..8c79c3f5 --- /dev/null +++ b/src/test/java/coffeemeet/server/user/implement/UserCommandTest.java @@ -0,0 +1,61 @@ +package coffeemeet.server.user.implement; + +import static coffeemeet.server.common.fixture.entity.UserFixture.token; +import static coffeemeet.server.common.fixture.entity.UserFixture.user; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; + +import coffeemeet.server.user.domain.User; +import coffeemeet.server.user.infrastructure.InterestRepository; +import coffeemeet.server.user.infrastructure.UserRepository; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class UserCommandTest { + + @InjectMocks + private UserCommand userCommand; + + @Mock + private UserRepository userRepository; + + @Mock + private UserQuery userQuery; + + @Mock + private InterestRepository interestRepository; + + @Test + @DisplayName("알림 정보를 등록하거나 업데이트할 수 있다.") + void registerOrUpdateNotificationToken() { + // given + User user = user(); + String token = token(); + given(userQuery.getUserById(user.getId())).willReturn(user); + + // when + userCommand.registerOrUpdateNotificationToken(user.getId(), token); + + // then + assertThat(user.getNotificationInfo().getToken()).isEqualTo(token); + } + + @Test + @DisplayName("푸시 알림을 거부할 수 있다.") + void unsubscribeNotification() { + User user = user(); + given(userQuery.getUserById(user.getId())).willReturn(user); + + // when + userCommand.unsubscribeNotification(user.getId()); + + // then + assertThat(user.getNotificationInfo().isSubscribedToNotification()).isFalse(); + } + +} From 6b2031af78ba2abacb1c1fb38bcd17532d142b35 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 17:09:29 +0900 Subject: [PATCH 18/45] =?UTF-8?q?feat:=20=EC=95=8C=EB=A6=BC=20=EB=B3=B4?= =?UTF-8?q?=EB=82=B4=EA=B8=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../implement/FCMNotificationSender.java | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 src/main/java/coffeemeet/server/common/implement/FCMNotificationSender.java diff --git a/src/main/java/coffeemeet/server/common/implement/FCMNotificationSender.java b/src/main/java/coffeemeet/server/common/implement/FCMNotificationSender.java new file mode 100644 index 00000000..c927a752 --- /dev/null +++ b/src/main/java/coffeemeet/server/common/implement/FCMNotificationSender.java @@ -0,0 +1,80 @@ +package coffeemeet.server.common.implement; + +import static coffeemeet.server.common.execption.GlobalErrorCode.INVALID_FCM_TOKEN; +import static coffeemeet.server.common.execption.GlobalErrorCode.PUSH_NOTIFICATION_SEND_FAILURE; +import static com.google.firebase.messaging.MessagingErrorCode.INVALID_ARGUMENT; +import static com.google.firebase.messaging.MessagingErrorCode.UNREGISTERED; + +import coffeemeet.server.common.execption.InvalidNotificationTokenException; +import coffeemeet.server.common.execption.NotificationFailException; +import coffeemeet.server.user.domain.NotificationInfo; +import com.google.firebase.messaging.FirebaseMessaging; +import com.google.firebase.messaging.FirebaseMessagingException; +import com.google.firebase.messaging.Message; +import com.google.firebase.messaging.MessagingErrorCode; +import com.google.firebase.messaging.MulticastMessage; +import com.google.firebase.messaging.Notification; +import java.util.Set; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class FCMNotificationSender { + + private final FirebaseMessaging firebaseMessaging; + private static final String INVALID_FCM_TOKEN_MESSAGE = "사용된 토큰(%s)이 유효하지 않습니다."; + private static final String PUSH_NOTIFICATION_SEND_FAILURE_MESSAGE = "푸시 알림 전송에 실패했습니다. 토큰: %s"; + + public void sendNotificationByToken(NotificationInfo notificationInfo, String content) { + if (!notificationInfo.isSubscribedToNotification()) { + return; + } + + Notification notification = createNotification(content); + Message message = Message.builder().setToken(notificationInfo.getToken()) + .setNotification(notification) + .build(); + + try { + firebaseMessaging.send(message); + } catch (FirebaseMessagingException e) { + handleFirebaseMessagingException(e, notificationInfo.getToken()); + } + } + + public void sendNotificationByTokens(Set notificationInfos, String content) { + notificationInfos.removeIf(notificationInfo -> !notificationInfo.isSubscribedToNotification()); + + Set tokens = notificationInfos.stream().map( + NotificationInfo::getToken + ).collect(Collectors.toUnmodifiableSet()); + + Notification notification = createNotification(content); + MulticastMessage message = MulticastMessage.builder().addAllTokens(tokens) + .setNotification(notification).build(); + + try { + firebaseMessaging.sendMulticast(message); + } catch (FirebaseMessagingException e) { + handleFirebaseMessagingException(e, String.join(", ", tokens)); // + } + } + + private void handleFirebaseMessagingException(FirebaseMessagingException e, String token) { + MessagingErrorCode messagingErrorCode = e.getMessagingErrorCode(); + + if (messagingErrorCode == UNREGISTERED || messagingErrorCode == INVALID_ARGUMENT) { + throw new InvalidNotificationTokenException(INVALID_FCM_TOKEN, + String.format(INVALID_FCM_TOKEN_MESSAGE, token)); + } + throw new NotificationFailException(PUSH_NOTIFICATION_SEND_FAILURE, + String.format(PUSH_NOTIFICATION_SEND_FAILURE_MESSAGE, token)); + } + + private Notification createNotification(String content) { + return Notification.builder().setTitle("커피밋").setBody(content).build(); + } + +} From 78be753c4d88484fce937a7239f44f4b19e11e30 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 17:09:38 +0900 Subject: [PATCH 19/45] =?UTF-8?q?test:=20=EC=95=8C=EB=A6=BC=20=EB=B3=B4?= =?UTF-8?q?=EB=82=B4=EA=B8=B0=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../implement/FCMNotificationSenderTest.java | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/test/java/coffeemeet/server/common/implement/FCMNotificationSenderTest.java diff --git a/src/test/java/coffeemeet/server/common/implement/FCMNotificationSenderTest.java b/src/test/java/coffeemeet/server/common/implement/FCMNotificationSenderTest.java new file mode 100644 index 00000000..9b264fbf --- /dev/null +++ b/src/test/java/coffeemeet/server/common/implement/FCMNotificationSenderTest.java @@ -0,0 +1,60 @@ +package coffeemeet.server.common.implement; + +import static coffeemeet.server.common.fixture.entity.UserFixture.content; +import static coffeemeet.server.common.fixture.entity.UserFixture.notificationInfo; +import static coffeemeet.server.common.fixture.entity.UserFixture.notificationInfos; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.only; + +import coffeemeet.server.user.domain.NotificationInfo; +import com.google.firebase.messaging.FirebaseMessaging; +import com.google.firebase.messaging.FirebaseMessagingException; +import java.util.Set; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class FCMNotificationSenderTest { + + @InjectMocks + private FCMNotificationSender fcmNotificationSender; + + @Mock + private FirebaseMessaging firebaseMessaging; + + @Test + void sendNotificationByTokenTest() throws FirebaseMessagingException { + // given + NotificationInfo notificationInfo = notificationInfo(); + String content = content(); + + given(firebaseMessaging.send(any())).willReturn(any()); + + // when + fcmNotificationSender.sendNotificationByToken(notificationInfo, content); + + // then + then(firebaseMessaging).should(only()).send(any()); + } + + @Test + void sendNotificationByTokens() throws FirebaseMessagingException { + // given + Set notificationInfos = notificationInfos(); + String content = content(); + + given(firebaseMessaging.sendMulticast(any())).willReturn(any()); + + // when + fcmNotificationSender.sendNotificationByTokens(notificationInfos, content); + + // then + then(firebaseMessaging).should(only()).sendMulticast(any()); + } + +} From b3894071b9598733983bdd823d8014305e905312 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 17:37:03 +0900 Subject: [PATCH 20/45] =?UTF-8?q?refactor:=20code=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/common/execption/GlobalErrorCode.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/coffeemeet/server/common/execption/GlobalErrorCode.java b/src/main/java/coffeemeet/server/common/execption/GlobalErrorCode.java index 3e1a8146..89037fb5 100644 --- a/src/main/java/coffeemeet/server/common/execption/GlobalErrorCode.java +++ b/src/main/java/coffeemeet/server/common/execption/GlobalErrorCode.java @@ -8,11 +8,11 @@ public enum GlobalErrorCode implements ErrorCode { VALIDATION_ERROR("G000", "유효하지 않은 입력입니다."), - INVALID_FCM_TOKEN("G001", "유효하지 않은 FCM토큰입니다."), - PUSH_NOTIFICATION_SEND_FAILURE("G002", "푸시 알림 전송에 실패했습니다."), + INVALID_FCM_TOKEN("G004", "유효하지 않은 FCM토큰입니다."), INVALID_S3_URL("G004", "유효하지 않은 s3 URL 입니다."), STOMP_ACCESSOR_NOT_FOUND("G005", "웹소켓 연결을 할 수 없습니다."), - INTERNAL_SERVER_ERROR("G050", "예상치 못한 오류입니다."); + INTERNAL_SERVER_ERROR("G050", "예상치 못한 오류입니다."), + PUSH_NOTIFICATION_SEND_FAILURE("G050", "푸시 알림 전송에 실패했습니다."); private final String code; private final String message; From 81ef481bcbac7bb881a20f73538704ff5919e396 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 17:44:56 +0900 Subject: [PATCH 21/45] =?UTF-8?q?refactor:=20isSubscribedToNotification=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/user/domain/NotificationInfo.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/coffeemeet/server/user/domain/NotificationInfo.java b/src/main/java/coffeemeet/server/user/domain/NotificationInfo.java index 86f1869a..05fe252c 100644 --- a/src/main/java/coffeemeet/server/user/domain/NotificationInfo.java +++ b/src/main/java/coffeemeet/server/user/domain/NotificationInfo.java @@ -23,6 +23,7 @@ public class NotificationInfo { public NotificationInfo(String token, LocalDateTime createdTokenAt) { this.token = token; + this.isSubscribedToNotification = true; this.createdTokenAt = createdTokenAt; } From 4732a8310e360f3879789e449b22bccd012b112e Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 17:45:24 +0900 Subject: [PATCH 22/45] =?UTF-8?q?style:=20=ED=8F=AC=EB=A7=B7=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/common/implement/FCMNotificationSender.java | 2 +- .../common/presentation/advice/GlobalExceptionHandler.java | 3 ++- .../coffeemeet/server/user/presentation/UserController.java | 2 +- .../presentation/CertificationControllerTest.java | 2 -- .../java/coffeemeet/server/user/service/UserServiceTest.java | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/coffeemeet/server/common/implement/FCMNotificationSender.java b/src/main/java/coffeemeet/server/common/implement/FCMNotificationSender.java index c927a752..5f315901 100644 --- a/src/main/java/coffeemeet/server/common/implement/FCMNotificationSender.java +++ b/src/main/java/coffeemeet/server/common/implement/FCMNotificationSender.java @@ -23,9 +23,9 @@ @RequiredArgsConstructor public class FCMNotificationSender { - private final FirebaseMessaging firebaseMessaging; private static final String INVALID_FCM_TOKEN_MESSAGE = "사용된 토큰(%s)이 유효하지 않습니다."; private static final String PUSH_NOTIFICATION_SEND_FAILURE_MESSAGE = "푸시 알림 전송에 실패했습니다. 토큰: %s"; + private final FirebaseMessaging firebaseMessaging; public void sendNotificationByToken(NotificationInfo notificationInfo, String content) { if (!notificationInfo.isSubscribedToNotification()) { diff --git a/src/main/java/coffeemeet/server/common/presentation/advice/GlobalExceptionHandler.java b/src/main/java/coffeemeet/server/common/presentation/advice/GlobalExceptionHandler.java index aa861ae7..a5ce0cd4 100644 --- a/src/main/java/coffeemeet/server/common/presentation/advice/GlobalExceptionHandler.java +++ b/src/main/java/coffeemeet/server/common/presentation/advice/GlobalExceptionHandler.java @@ -52,7 +52,8 @@ public ResponseEntity handleException(InvalidInputException excep } @ExceptionHandler(InvalidNotificationTokenException.class) - public ResponseEntity handleException(InvalidNotificationTokenException exception) { + public ResponseEntity handleException( + InvalidNotificationTokenException exception) { log.info(exception.getMessage(), exception); return ResponseEntity.status(HttpStatus.NOT_FOUND) .body(ErrorResponse.of(exception.getErrorCode())); diff --git a/src/main/java/coffeemeet/server/user/presentation/UserController.java b/src/main/java/coffeemeet/server/user/presentation/UserController.java index 16e885f7..7320741d 100644 --- a/src/main/java/coffeemeet/server/user/presentation/UserController.java +++ b/src/main/java/coffeemeet/server/user/presentation/UserController.java @@ -3,10 +3,10 @@ import coffeemeet.server.auth.domain.AuthTokens; import coffeemeet.server.common.annotation.Login; import coffeemeet.server.common.domain.AuthInfo; -import coffeemeet.server.user.presentation.dto.NotificationTokenHTTP; import coffeemeet.server.common.util.FileUtils; import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.presentation.dto.MyProfileHTTP; +import coffeemeet.server.user.presentation.dto.NotificationTokenHTTP; import coffeemeet.server.user.presentation.dto.SignupHTTP; import coffeemeet.server.user.presentation.dto.UpdateProfileHTTP; import coffeemeet.server.user.presentation.dto.UserProfileHTTP; diff --git a/src/test/java/coffeemeet/server/certification/presentation/CertificationControllerTest.java b/src/test/java/coffeemeet/server/certification/presentation/CertificationControllerTest.java index 76a5b382..80b3c2d5 100644 --- a/src/test/java/coffeemeet/server/certification/presentation/CertificationControllerTest.java +++ b/src/test/java/coffeemeet/server/certification/presentation/CertificationControllerTest.java @@ -8,10 +8,8 @@ import static coffeemeet.server.common.fixture.entity.CertificationFixture.verificationCodeDtoRequest; import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.resourceDetails; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.willDoNothing; import static org.springframework.http.HttpHeaders.AUTHORIZATION; import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.http.MediaType.MULTIPART_FORM_DATA; diff --git a/src/test/java/coffeemeet/server/user/service/UserServiceTest.java b/src/test/java/coffeemeet/server/user/service/UserServiceTest.java index b330f21b..298abd97 100644 --- a/src/test/java/coffeemeet/server/user/service/UserServiceTest.java +++ b/src/test/java/coffeemeet/server/user/service/UserServiceTest.java @@ -290,7 +290,7 @@ void registerOrUpdateNotificationTokenTest() { willDoNothing().given(userCommand).registerOrUpdateNotificationToken(any(), any()); // when - userService.registerOrUpdateNotificationToken(any(),any()); + userService.registerOrUpdateNotificationToken(any(), any()); // then then(userCommand).should(only()).registerOrUpdateNotificationToken(any(), any()); From 4067bb722ad26503b8b2cb7a804adeb071547853 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 18:04:02 +0900 Subject: [PATCH 23/45] =?UTF-8?q?refactor:=20=EC=98=88=EC=99=B8=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EB=B0=A9=EC=8B=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../InvalidNotificationTokenException.java | 15 --------------- .../common/implement/FCMNotificationSender.java | 4 ++-- .../advice/GlobalExceptionHandler.java | 9 --------- 3 files changed, 2 insertions(+), 26 deletions(-) delete mode 100644 src/main/java/coffeemeet/server/common/execption/InvalidNotificationTokenException.java diff --git a/src/main/java/coffeemeet/server/common/execption/InvalidNotificationTokenException.java b/src/main/java/coffeemeet/server/common/execption/InvalidNotificationTokenException.java deleted file mode 100644 index 3b1ec802..00000000 --- a/src/main/java/coffeemeet/server/common/execption/InvalidNotificationTokenException.java +++ /dev/null @@ -1,15 +0,0 @@ -package coffeemeet.server.common.execption; - -import lombok.Getter; - -@Getter -public class InvalidNotificationTokenException extends CoffeeMeetException { - - private final ErrorCode errorCode; - - public InvalidNotificationTokenException(ErrorCode errorCode, String message) { - super(message); - this.errorCode = errorCode; - } - -} diff --git a/src/main/java/coffeemeet/server/common/implement/FCMNotificationSender.java b/src/main/java/coffeemeet/server/common/implement/FCMNotificationSender.java index 5f315901..3ac96c84 100644 --- a/src/main/java/coffeemeet/server/common/implement/FCMNotificationSender.java +++ b/src/main/java/coffeemeet/server/common/implement/FCMNotificationSender.java @@ -5,7 +5,7 @@ import static com.google.firebase.messaging.MessagingErrorCode.INVALID_ARGUMENT; import static com.google.firebase.messaging.MessagingErrorCode.UNREGISTERED; -import coffeemeet.server.common.execption.InvalidNotificationTokenException; +import coffeemeet.server.common.execption.InvalidInputException; import coffeemeet.server.common.execption.NotificationFailException; import coffeemeet.server.user.domain.NotificationInfo; import com.google.firebase.messaging.FirebaseMessaging; @@ -66,7 +66,7 @@ private void handleFirebaseMessagingException(FirebaseMessagingException e, Stri MessagingErrorCode messagingErrorCode = e.getMessagingErrorCode(); if (messagingErrorCode == UNREGISTERED || messagingErrorCode == INVALID_ARGUMENT) { - throw new InvalidNotificationTokenException(INVALID_FCM_TOKEN, + throw new InvalidInputException(INVALID_FCM_TOKEN, String.format(INVALID_FCM_TOKEN_MESSAGE, token)); } throw new NotificationFailException(PUSH_NOTIFICATION_SEND_FAILURE, diff --git a/src/main/java/coffeemeet/server/common/presentation/advice/GlobalExceptionHandler.java b/src/main/java/coffeemeet/server/common/presentation/advice/GlobalExceptionHandler.java index a5ce0cd4..68988ce5 100644 --- a/src/main/java/coffeemeet/server/common/presentation/advice/GlobalExceptionHandler.java +++ b/src/main/java/coffeemeet/server/common/presentation/advice/GlobalExceptionHandler.java @@ -4,7 +4,6 @@ import coffeemeet.server.common.execption.GlobalErrorCode; import coffeemeet.server.common.execption.InvalidAuthException; import coffeemeet.server.common.execption.InvalidInputException; -import coffeemeet.server.common.execption.InvalidNotificationTokenException; import coffeemeet.server.common.execption.MissMatchException; import coffeemeet.server.common.execption.NotFoundException; import lombok.RequiredArgsConstructor; @@ -51,14 +50,6 @@ public ResponseEntity handleException(InvalidInputException excep .body(ErrorResponse.of(exception.getErrorCode())); } - @ExceptionHandler(InvalidNotificationTokenException.class) - public ResponseEntity handleException( - InvalidNotificationTokenException exception) { - log.info(exception.getMessage(), exception); - return ResponseEntity.status(HttpStatus.NOT_FOUND) - .body(ErrorResponse.of(exception.getErrorCode())); - } - @ExceptionHandler(MissMatchException.class) public ResponseEntity handleException(MissMatchException exception) { log.info(exception.getMessage(), exception); From 6b12e183aa404b3a3d78a9cacf67cc4326a7c0e8 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 18:31:47 +0900 Subject: [PATCH 24/45] =?UTF-8?q?refactor:=20=EC=A0=95=EC=A0=81=20?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A6=AC=20=EB=B0=A9=EC=8B=9D=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/user/domain/NotificationInfo.java | 11 ++++++++--- .../coffeemeet/server/user/implement/UserCommand.java | 5 +++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/domain/NotificationInfo.java b/src/main/java/coffeemeet/server/user/domain/NotificationInfo.java index 05fe252c..ee6e0d6c 100644 --- a/src/main/java/coffeemeet/server/user/domain/NotificationInfo.java +++ b/src/main/java/coffeemeet/server/user/domain/NotificationInfo.java @@ -21,14 +21,19 @@ public class NotificationInfo { @Column(name = "created_firebase_notification_token_at") private LocalDateTime createdTokenAt; - public NotificationInfo(String token, LocalDateTime createdTokenAt) { + private NotificationInfo(String token, LocalDateTime createdTokenAt) { this.token = token; this.isSubscribedToNotification = true; this.createdTokenAt = createdTokenAt; } - public NotificationInfo(boolean isSubscribedToNotification) { - this.isSubscribedToNotification = isSubscribedToNotification; + public static NotificationInfo createApprovedNotificationInfo(String token, + LocalDateTime createdTokenAt) { + return new NotificationInfo(token, createdTokenAt); + } + + public static NotificationInfo createRefusedNotificationInfo() { + return new NotificationInfo(); } } diff --git a/src/main/java/coffeemeet/server/user/implement/UserCommand.java b/src/main/java/coffeemeet/server/user/implement/UserCommand.java index bb218796..68df104e 100644 --- a/src/main/java/coffeemeet/server/user/implement/UserCommand.java +++ b/src/main/java/coffeemeet/server/user/implement/UserCommand.java @@ -38,12 +38,13 @@ public void updateUserInfo(User user, String nickname) { public void registerOrUpdateNotificationToken(Long userId, String token) { User user = userQuery.getUserById(userId); - user.updateNotificationInfo(new NotificationInfo(token, LocalDateTime.now())); + user.updateNotificationInfo( + NotificationInfo.createApprovedNotificationInfo(token, LocalDateTime.now())); } public void unsubscribeNotification(Long userId) { User user = userQuery.getUserById(userId); - user.updateNotificationInfo(new NotificationInfo(false)); + user.updateNotificationInfo(NotificationInfo.createRefusedNotificationInfo()); } } From 0619375c23cee7c8b8ecf398c81425f3c384dd71 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 7 Nov 2023 18:47:40 +0900 Subject: [PATCH 25/45] =?UTF-8?q?chore:=20firebase=20key=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +++ .../coffeemeet/server/common/config/FirebaseConfig.java | 8 +------- src/main/resources/application.yml | 3 --- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 55608a8e..be7b45ee 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,6 @@ out/ ### VS Code ### .vscode/ + +### FIREBASE ### +firebase-service-key.json diff --git a/src/main/java/coffeemeet/server/common/config/FirebaseConfig.java b/src/main/java/coffeemeet/server/common/config/FirebaseConfig.java index f5ede6ca..165aa744 100644 --- a/src/main/java/coffeemeet/server/common/config/FirebaseConfig.java +++ b/src/main/java/coffeemeet/server/common/config/FirebaseConfig.java @@ -5,7 +5,6 @@ import com.google.firebase.FirebaseOptions; import com.google.firebase.messaging.FirebaseMessaging; import java.io.IOException; -import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; @@ -13,14 +12,9 @@ @Configuration public class FirebaseConfig { - private final String filename; - - public FirebaseConfig(@Value("${cloud.firebase.key-path}") String filename) { - this.filename = filename; - } - @Bean FirebaseApp firebaseApp() throws IOException { + String filename = "firebase-service-key.json"; ClassPathResource resource = new ClassPathResource(filename); FirebaseOptions options = FirebaseOptions.builder() diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 6f4dbad3..9bb9559e 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -61,6 +61,3 @@ cloud: auto: false stack: auto: false - firebase: - key-path: - ${CLOUD_FIREBASE_KEY_PATH} From 07fe336ca3f85afc3549a953db2963f698e825c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 7 Nov 2023 20:07:27 +0900 Subject: [PATCH 26/45] =?UTF-8?q?refactor:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EA=B8=B0=EB=B3=B8=EA=B0=92=20?= =?UTF-8?q?=EC=A7=80=EC=A0=95=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kakao/dto/KakaoMemberDetail.java | 15 ++++++++++++++- .../server/user/service/UserService.java | 12 +----------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberDetail.java b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberDetail.java index 0f12b042..47efe45c 100644 --- a/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberDetail.java +++ b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberDetail.java @@ -4,6 +4,7 @@ import coffeemeet.server.user.domain.OAuthProvider; import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; import com.fasterxml.jackson.databind.annotation.JsonNaming; +import jakarta.annotation.Nullable; @JsonNaming(SnakeCaseStrategy.class) public record KakaoMemberDetail( @@ -11,9 +12,13 @@ public record KakaoMemberDetail( KakaoAccount kakaoAccount ) { + private static final String DEFAULT_IMAGE_URL = "기본 이미지 URL"; + public OAuthMemberDetail toOAuthMemberDetail() { + String profileImageUrl = kakaoAccount.profile != null ? kakaoAccount.profile.profileImageUrl : null; + return OAuthMemberDetail.of( - kakaoAccount.profile.profileImageUrl, + getProfileImageOrDefault(profileImageUrl), kakaoAccount.email, OAuthProvider.KAKAO, String.valueOf(id) @@ -30,9 +35,17 @@ private record KakaoAccount( @JsonNaming(SnakeCaseStrategy.class) private record Profile( + @Nullable String profileImageUrl ) { } + private String getProfileImageOrDefault(String profileImageUrl) { + if (profileImageUrl == null) { + profileImageUrl = DEFAULT_IMAGE_URL; + } + return profileImageUrl; + } + } diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 455430cf..1c378eee 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -31,8 +31,6 @@ @RequiredArgsConstructor public class UserService { - private static final String DEFAULT_IMAGE_URL = "기본 이미지 URL"; - private final MediaManager mediaManager; private final OAuthMemberClientComposite oAuthMemberClientComposite; @@ -51,11 +49,10 @@ public AuthTokens signup(String nickname, List keywords, String authCod userQuery.hasDuplicatedUser(memberDetail.oAuthProvider(), memberDetail.oAuthProviderId()); userQuery.hasDuplicatedNickname(nickname); - String profileImage = getProfileImageOrDefault(memberDetail.profileImage()); User user = new User(new OAuthInfo(memberDetail.oAuthProvider(), memberDetail.oAuthProviderId()), - new Profile(nickname, new Email(memberDetail.email()), profileImage) + new Profile(nickname, new Email(memberDetail.email()), memberDetail.profileImage()) ); Long userId = userCommand.saveUser(user); @@ -115,13 +112,6 @@ public void deleteUser(Long userId) { userCommand.deleteUser(userId); } - private String getProfileImageOrDefault(String profileImage) { - if (profileImage == null) { - profileImage = DEFAULT_IMAGE_URL; - } - return profileImage; - } - private void deleteCurrentProfileImage(String profileImageUrl) { String currentKey = mediaManager.extractKey(profileImageUrl, PROFILE_IMAGE); From 0812f0b2b14c7c3b3571f40e14be73b259e23b18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Wed, 8 Nov 2023 14:22:39 +0900 Subject: [PATCH 27/45] =?UTF-8?q?test:=20=EB=B3=80=EA=B2=BD=EB=90=9C=20?= =?UTF-8?q?=EC=9C=A0=EC=A0=80=20=ED=94=84=EB=A1=9C=ED=95=84=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=EC=97=90=20=EB=94=B0=EB=9D=BC=20UserFixture=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/common/fixture/entity/UserFixture.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java b/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java index a6a0b27a..a8274c46 100644 --- a/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java @@ -19,7 +19,7 @@ public static User user() { } private static Profile profile() { - return Instancio.of(Profile.class).set(field(Profile::getBirth), birth()) + return Instancio.of(Profile.class) .set(field(Profile::getEmail), new Email("test123@gmail.com")) .generate(field(Profile::getNickname), gen -> gen.string().maxLength(20)).create(); } From 7c4b2c920e44e787c1870b625ed232a9fe17e6c6 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 8 Nov 2023 14:30:45 +0900 Subject: [PATCH 28/45] =?UTF-8?q?feat:=20=EC=A0=95=EC=A0=81=20=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ChattingDto 로부터 ChatStomp 생성 --- .../chatting/current/presentation/dto/ChatStomp.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/coffeemeet/server/chatting/current/presentation/dto/ChatStomp.java b/src/main/java/coffeemeet/server/chatting/current/presentation/dto/ChatStomp.java index 9e0a6ece..6097c252 100644 --- a/src/main/java/coffeemeet/server/chatting/current/presentation/dto/ChatStomp.java +++ b/src/main/java/coffeemeet/server/chatting/current/presentation/dto/ChatStomp.java @@ -1,5 +1,6 @@ package coffeemeet.server.chatting.current.presentation.dto; +import coffeemeet.server.chatting.current.service.dto.ChattingDto; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import java.time.LocalDateTime; @@ -21,6 +22,14 @@ record Response( LocalDateTime createdAt ) implements ChatStomp { + public static ChatStomp.Response from(ChattingDto.Response response) { + return new ChatStomp.Response( + response.nickname(), + response.content(), + response.createdAt() + ); + } + } } From ee69ced698d12f8f777e60d3c1a294f3ee246b28 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 8 Nov 2023 14:31:00 +0900 Subject: [PATCH 29/45] =?UTF-8?q?feat:=20ChattingDto=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../current/service/dto/ChattingDto.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/main/java/coffeemeet/server/chatting/current/service/dto/ChattingDto.java diff --git a/src/main/java/coffeemeet/server/chatting/current/service/dto/ChattingDto.java b/src/main/java/coffeemeet/server/chatting/current/service/dto/ChattingDto.java new file mode 100644 index 00000000..79e026cc --- /dev/null +++ b/src/main/java/coffeemeet/server/chatting/current/service/dto/ChattingDto.java @@ -0,0 +1,25 @@ +package coffeemeet.server.chatting.current.service.dto; + +import coffeemeet.server.chatting.current.domain.ChattingMessage; +import coffeemeet.server.user.domain.User; +import java.time.LocalDateTime; + +public sealed interface ChattingDto permits ChattingDto.Response { + + record Response( + String nickname, + String content, + LocalDateTime createdAt + ) implements ChattingDto { + + public static Response of(User user, ChattingMessage chattingMessage) { + return new Response( + user.getProfile().getNickname(), + chattingMessage.getMessage(), + chattingMessage.getCreatedAt() + ); + } + + } + +} From bce3ae77cb2b9218b779c695de68541b3e6e307c Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 8 Nov 2023 14:32:05 +0900 Subject: [PATCH 30/45] =?UTF-8?q?feat:=20=EC=B1=84=ED=8C=85=20=EB=82=B4?= =?UTF-8?q?=EC=97=AD=EC=9D=84=20DB=EC=97=90=20=EC=A0=80=EC=9E=A5=ED=95=98?= =?UTF-8?q?=EA=B3=A0,=20=EC=B1=84=ED=8C=85=20=EC=9D=91=EB=8B=B5=EC=9D=84?= =?UTF-8?q?=20=EB=A7=8C=EB=93=A4=EC=96=B4=20=EB=B0=98=ED=99=98=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chatting/current/service/ChattingMessageService.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/chatting/current/service/ChattingMessageService.java b/src/main/java/coffeemeet/server/chatting/current/service/ChattingMessageService.java index 7f4de1d9..e27e2a26 100644 --- a/src/main/java/coffeemeet/server/chatting/current/service/ChattingMessageService.java +++ b/src/main/java/coffeemeet/server/chatting/current/service/ChattingMessageService.java @@ -1,8 +1,10 @@ package coffeemeet.server.chatting.current.service; +import coffeemeet.server.chatting.current.domain.ChattingMessage; import coffeemeet.server.chatting.current.domain.ChattingRoom; import coffeemeet.server.chatting.current.implement.ChattingMessageCommand; import coffeemeet.server.chatting.current.implement.ChattingRoomQuery; +import coffeemeet.server.chatting.current.service.dto.ChattingDto; import coffeemeet.server.user.domain.User; import coffeemeet.server.user.implement.UserQuery; import lombok.RequiredArgsConstructor; @@ -16,10 +18,12 @@ public class ChattingMessageService { private final ChattingRoomQuery chattingRoomQuery; private final UserQuery userQuery; - public void createChattingMessage(Long roomId, String content, Long userId) { + public ChattingDto.Response chatting(Long roomId, String content, Long userId) { User user = userQuery.getUserById(userId); ChattingRoom chattingRoom = chattingRoomQuery.getChattingRoomById(roomId); - chattingMessageCommand.saveChattingMessage(content, chattingRoom, user); + ChattingMessage chattingMessage = chattingMessageCommand.saveChattingMessage(content, + chattingRoom, user); + return ChattingDto.Response.of(user, chattingMessage); } } From 086d0b548954396c798b9d911fe7ac6ee2a1125a Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 8 Nov 2023 14:32:33 +0900 Subject: [PATCH 31/45] =?UTF-8?q?test:=20chattingTest=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/ChattingMessageServiceTest.java | 33 ++++++++++++------- .../fixture/entity/ChattingFixture.java | 8 +++++ 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/test/java/coffeemeet/server/chatting/current/service/ChattingMessageServiceTest.java b/src/test/java/coffeemeet/server/chatting/current/service/ChattingMessageServiceTest.java index 96d12f12..34554c47 100644 --- a/src/test/java/coffeemeet/server/chatting/current/service/ChattingMessageServiceTest.java +++ b/src/test/java/coffeemeet/server/chatting/current/service/ChattingMessageServiceTest.java @@ -1,11 +1,17 @@ package coffeemeet.server.chatting.current.service; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.only; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.BDDMockito.given; +import coffeemeet.server.chatting.current.domain.ChattingMessage; +import coffeemeet.server.chatting.current.domain.ChattingRoom; import coffeemeet.server.chatting.current.implement.ChattingMessageCommand; import coffeemeet.server.chatting.current.implement.ChattingRoomQuery; +import coffeemeet.server.chatting.current.service.dto.ChattingDto.Response; +import coffeemeet.server.common.fixture.entity.ChattingFixture; +import coffeemeet.server.common.fixture.entity.UserFixture; +import coffeemeet.server.user.domain.User; import coffeemeet.server.user.implement.UserQuery; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -29,21 +35,26 @@ class ChattingMessageServiceTest { @Mock private UserQuery userQuery; - @DisplayName("채팅 메세지를 만들 수 있다.") + @DisplayName("채팅 메세지를 만들고, 클라이언트에 채팅 응답을 반환할 수 있다.") @Test - void createChattingMessageTest() { + void chattingTest() { // given - Long roomId = 1L; + User user = UserFixture.user(); + ChattingRoom chattingRoom = ChattingFixture.chattingRoom(); String content = "내용"; - Long userId = 1L; + ChattingMessage chattingMessage = ChattingFixture.chattingMessage(content); + + given(userQuery.getUserById(anyLong())).willReturn(user); + given(chattingRoomQuery.getChattingRoomById(anyLong())).willReturn(chattingRoom); + given(chattingMessageCommand.saveChattingMessage(content, chattingRoom, user)).willReturn( + chattingMessage); // when - chattingMessageService.createChattingMessage(roomId, content, userId); + Response response = chattingMessageService.chatting(chattingRoom.getId(), content, + user.getId()); // then - then(userQuery).should(only()).getUserById(userId); - then(chattingRoomQuery).should(only()).getChattingRoomById(roomId); - then(chattingMessageCommand).should(only()).saveChattingMessage(any(), any(), any()); + assertThat(response.content()).isEqualTo(content); } } diff --git a/src/test/java/coffeemeet/server/common/fixture/entity/ChattingFixture.java b/src/test/java/coffeemeet/server/common/fixture/entity/ChattingFixture.java index 47ddba1d..6e807318 100644 --- a/src/test/java/coffeemeet/server/common/fixture/entity/ChattingFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/entity/ChattingFixture.java @@ -1,5 +1,7 @@ package coffeemeet.server.common.fixture.entity; +import static org.instancio.Select.field; + import coffeemeet.server.chatting.current.domain.ChattingMessage; import coffeemeet.server.chatting.current.domain.ChattingRoom; import coffeemeet.server.chatting.current.presentation.dto.ChatStomp; @@ -12,6 +14,12 @@ public static ChattingMessage chattingMessage() { .create(); } + public static ChattingMessage chattingMessage(String content) { + return Instancio.of(ChattingMessage.class) + .set(field(ChattingMessage::getMessage), content) + .create(); + } + public static ChattingRoom chattingRoom() { return Instancio.of(ChattingRoom.class) .create(); From a265dbf321a7441cf9e7d832784593cc8b949e2f Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 8 Nov 2023 14:33:22 +0900 Subject: [PATCH 32/45] =?UTF-8?q?test:=20message()=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../current/presentation/ChattingMessageController.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/coffeemeet/server/chatting/current/presentation/ChattingMessageController.java b/src/main/java/coffeemeet/server/chatting/current/presentation/ChattingMessageController.java index ffd5f7e0..565f1b1c 100644 --- a/src/main/java/coffeemeet/server/chatting/current/presentation/ChattingMessageController.java +++ b/src/main/java/coffeemeet/server/chatting/current/presentation/ChattingMessageController.java @@ -1,10 +1,9 @@ package coffeemeet.server.chatting.current.presentation; import coffeemeet.server.chatting.current.presentation.dto.ChatStomp; -import coffeemeet.server.chatting.current.presentation.dto.ChatStomp.Response; import coffeemeet.server.chatting.current.service.ChattingMessageService; +import coffeemeet.server.chatting.current.service.dto.ChattingDto; import jakarta.validation.Valid; -import java.time.LocalDateTime; import java.util.HashMap; import java.util.Map; import lombok.RequiredArgsConstructor; @@ -42,10 +41,10 @@ public void onDisconnect(SessionDisconnectEvent event) { @MessageMapping("/chatting/messages") public void message(@Valid ChatStomp.Request request, SimpMessageHeaderAccessor accessor) { Long userId = sessions.get(accessor.getSessionId()); - chattingMessageService.createChattingMessage(request.roomId(), request.content(), userId); - log.info("채팅 = {}", request.content()); + ChattingDto.Response response = chattingMessageService.chatting(request.roomId(), + request.content(), userId); simpMessageSendingOperations.convertAndSend("/sub/chatting/rooms/" + request.roomId(), - new Response("유명한", request.content(), LocalDateTime.now())); + ChatStomp.Response.from(response)); } } From e2f7daadc5cdb4204a07e8a5ae6def77cf6479c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Wed, 8 Nov 2023 15:01:15 +0900 Subject: [PATCH 33/45] =?UTF-8?q?refactor:=20=ED=94=84=EB=A1=9C=ED=95=84?= =?UTF-8?q?=20=EA=B8=B0=EB=B3=B8=EC=83=9D=EC=84=B1=EC=9E=90=20=EC=A0=91?= =?UTF-8?q?=EA=B7=BC=EC=A0=9C=EC=96=B4=EC=9E=90=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/coffeemeet/server/user/domain/Profile.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/user/domain/Profile.java b/src/main/java/coffeemeet/server/user/domain/Profile.java index 11be2840..95a053f6 100644 --- a/src/main/java/coffeemeet/server/user/domain/Profile.java +++ b/src/main/java/coffeemeet/server/user/domain/Profile.java @@ -8,6 +8,7 @@ import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import jakarta.persistence.Embedded; +import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.NonNull; @@ -15,7 +16,7 @@ @Getter @Embeddable -@NoArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class Profile { private static final int NICKNAME_MAX_LENGTH = 20; From 14488e0bb41dceb114b26000b71eadce73842cb8 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 8 Nov 2023 15:44:01 +0900 Subject: [PATCH 34/45] feat: update cd script --- .github/workflows/cd.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 30fd5858..be915e67 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -31,6 +31,9 @@ jobs: - name: .env 파일에 깃 Secrets 로부터 값을 가져와 기록한다. run: echo "${{ secrets.ENV_PROPERTIES }}" > ./.env + - name: firebase-service-key.json 파일에 깃 Secrets 로부터 값을 가져와 기록한다. + run: echo "${{ secrets.FIREBASE_KEY }}" > ./src/main/resources/firebase-service-key.json + - name: Gradle 명령 실행을 위한 권한을 부여한다. run: chmod +x gradlew From a26cca7ea66567490c1bb014dc0da681d4e8ba5f Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 8 Nov 2023 15:50:23 +0900 Subject: [PATCH 35/45] feat: update yml --- src/main/resources/application.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 9bb9559e..e029a289 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -8,7 +8,7 @@ spring: open-in-view: false show-sql: true hibernate: - ddl-auto: validate + ddl-auto: create properties: hibernate: format_sql: true From 99fd7ff825dbaa3eec7c0d3f5426b7454813038b Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 8 Nov 2023 16:12:52 +0900 Subject: [PATCH 36/45] feat: code formatting --- .../kakao/dto/KakaoMemberDetail.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberDetail.java b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberDetail.java index 47efe45c..233914f7 100644 --- a/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberDetail.java +++ b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberDetail.java @@ -15,7 +15,8 @@ public record KakaoMemberDetail( private static final String DEFAULT_IMAGE_URL = "기본 이미지 URL"; public OAuthMemberDetail toOAuthMemberDetail() { - String profileImageUrl = kakaoAccount.profile != null ? kakaoAccount.profile.profileImageUrl : null; + String profileImageUrl = + kakaoAccount.profile != null ? kakaoAccount.profile.profileImageUrl : null; return OAuthMemberDetail.of( getProfileImageOrDefault(profileImageUrl), @@ -25,6 +26,13 @@ public OAuthMemberDetail toOAuthMemberDetail() { ); } + private String getProfileImageOrDefault(String profileImageUrl) { + if (profileImageUrl == null) { + profileImageUrl = DEFAULT_IMAGE_URL; + } + return profileImageUrl; + } + @JsonNaming(SnakeCaseStrategy.class) private record KakaoAccount( Profile profile, @@ -41,11 +49,4 @@ private record Profile( } - private String getProfileImageOrDefault(String profileImageUrl) { - if (profileImageUrl == null) { - profileImageUrl = DEFAULT_IMAGE_URL; - } - return profileImageUrl; - } - } From 7210ae2ded32f20a528f12c2b72e9cd4a32e2ba0 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 8 Nov 2023 16:14:00 +0900 Subject: [PATCH 37/45] feat: update cd script --- .github/workflows/cd.yml | 11 ++++++++++- .../server/common/config/FirebaseConfig.java | 8 ++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index be915e67..cc2973c9 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -32,7 +32,7 @@ jobs: run: echo "${{ secrets.ENV_PROPERTIES }}" > ./.env - name: firebase-service-key.json 파일에 깃 Secrets 로부터 값을 가져와 기록한다. - run: echo "${{ secrets.FIREBASE_KEY }}" > ./src/main/resources/firebase-service-key.json + run: echo "${{ secrets.FIREBASE_KEY }}" > ./firebase-service-key.json - name: Gradle 명령 실행을 위한 권한을 부여한다. run: chmod +x gradlew @@ -63,6 +63,15 @@ jobs: source: "./.env" target: "/home/ubuntu" + - name: firebase key 파일을 Ec2 서버의 기본 경로에 전달한다. + uses: appleboy/scp-action@master + with: + username: ubuntu + host: ${{ secrets.HOST }} + key: ${{ secrets.PRIVATE_KEY }} + source: "./firebase-service-key.json" + target: "/home/ubuntu" + - name: 기존의 Jar 이미지를 삭제하고, Docker Hub 를 통해 새 Jar 이미지를 실행한다. uses: appleboy/ssh-action@v1.0.0 with: diff --git a/src/main/java/coffeemeet/server/common/config/FirebaseConfig.java b/src/main/java/coffeemeet/server/common/config/FirebaseConfig.java index 165aa744..995594e8 100644 --- a/src/main/java/coffeemeet/server/common/config/FirebaseConfig.java +++ b/src/main/java/coffeemeet/server/common/config/FirebaseConfig.java @@ -4,21 +4,21 @@ import com.google.firebase.FirebaseApp; import com.google.firebase.FirebaseOptions; import com.google.firebase.messaging.FirebaseMessaging; +import java.io.FileInputStream; import java.io.IOException; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.core.io.ClassPathResource; @Configuration public class FirebaseConfig { @Bean FirebaseApp firebaseApp() throws IOException { - String filename = "firebase-service-key.json"; - ClassPathResource resource = new ClassPathResource(filename); + FileInputStream serviceAccount = + new FileInputStream("/home/ubuntu/firebase-service-key.json"); FirebaseOptions options = FirebaseOptions.builder() - .setCredentials(GoogleCredentials.fromStream(resource.getInputStream())).build(); + .setCredentials(GoogleCredentials.fromStream(serviceAccount)).build(); return FirebaseApp.initializeApp(options); } From eb7e9881411e4986f89773fb48dda11851f693fd Mon Sep 17 00:00:00 2001 From: sangminnim Date: Wed, 8 Nov 2023 17:08:51 +0900 Subject: [PATCH 38/45] =?UTF-8?q?chore:=20secret=EC=97=90=20=EC=9E=88?= =?UTF-8?q?=EB=8A=94=20=ED=82=A4=20=ED=8C=8C=EC=9D=BC=20=EB=B3=B5=EC=82=AC?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/build.gradle b/build.gradle index c1d7b7a5..b984d445 100644 --- a/build.gradle +++ b/build.gradle @@ -118,6 +118,14 @@ tasks.withType(GenerateSwaggerUI) { } } +task copyPrivate(type: Copy) { + copy { + from './secret' + include "firebase-service-key.json" + into 'src/main/resources' + } +} + bootJar { dependsOn generateSwaggerUISample from("${generateSwaggerUISample.outputDir}") { From 02dc731a3870d922c34fbd1c54fbb08aec3223ad Mon Sep 17 00:00:00 2001 From: sangminnim Date: Wed, 8 Nov 2023 17:09:19 +0900 Subject: [PATCH 39/45] =?UTF-8?q?refactor:=20=EC=9C=84=EC=B9=98=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/common/config/FirebaseConfig.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/coffeemeet/server/common/config/FirebaseConfig.java b/src/main/java/coffeemeet/server/common/config/FirebaseConfig.java index 995594e8..165aa744 100644 --- a/src/main/java/coffeemeet/server/common/config/FirebaseConfig.java +++ b/src/main/java/coffeemeet/server/common/config/FirebaseConfig.java @@ -4,21 +4,21 @@ import com.google.firebase.FirebaseApp; import com.google.firebase.FirebaseOptions; import com.google.firebase.messaging.FirebaseMessaging; -import java.io.FileInputStream; import java.io.IOException; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; @Configuration public class FirebaseConfig { @Bean FirebaseApp firebaseApp() throws IOException { - FileInputStream serviceAccount = - new FileInputStream("/home/ubuntu/firebase-service-key.json"); + String filename = "firebase-service-key.json"; + ClassPathResource resource = new ClassPathResource(filename); FirebaseOptions options = FirebaseOptions.builder() - .setCredentials(GoogleCredentials.fromStream(serviceAccount)).build(); + .setCredentials(GoogleCredentials.fromStream(resource.getInputStream())).build(); return FirebaseApp.initializeApp(options); } From f906dc87b0158772be8c697333098451d83f3f08 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Wed, 8 Nov 2023 17:09:39 +0900 Subject: [PATCH 40/45] =?UTF-8?q?feat:=20=EC=84=9C=EB=B8=8C=EB=AA=A8?= =?UTF-8?q?=EB=93=88=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 --- .gitmodules | 3 +++ secret | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 .gitmodules create mode 160000 secret diff --git a/.gitignore b/.gitignore index be7b45ee..55608a8e 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,3 @@ out/ ### VS Code ### .vscode/ - -### FIREBASE ### -firebase-service-key.json diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..56d84a4f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "secret"] + path = secret + url = https://github.com/coffee-meet/secret.git diff --git a/secret b/secret new file mode 160000 index 00000000..40b18d26 --- /dev/null +++ b/secret @@ -0,0 +1 @@ +Subproject commit 40b18d2606dfee6c3495cc143119bd041290664d From 504a39478a39df4197a9ab03509eaaf820a35527 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 8 Nov 2023 17:39:02 +0900 Subject: [PATCH 41/45] feat: update cd script --- .github/workflows/cd.yml | 12 ------------ .gitignore | 5 ++++- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index cc2973c9..30fd5858 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -31,9 +31,6 @@ jobs: - name: .env 파일에 깃 Secrets 로부터 값을 가져와 기록한다. run: echo "${{ secrets.ENV_PROPERTIES }}" > ./.env - - name: firebase-service-key.json 파일에 깃 Secrets 로부터 값을 가져와 기록한다. - run: echo "${{ secrets.FIREBASE_KEY }}" > ./firebase-service-key.json - - name: Gradle 명령 실행을 위한 권한을 부여한다. run: chmod +x gradlew @@ -63,15 +60,6 @@ jobs: source: "./.env" target: "/home/ubuntu" - - name: firebase key 파일을 Ec2 서버의 기본 경로에 전달한다. - uses: appleboy/scp-action@master - with: - username: ubuntu - host: ${{ secrets.HOST }} - key: ${{ secrets.PRIVATE_KEY }} - source: "./firebase-service-key.json" - target: "/home/ubuntu" - - name: 기존의 Jar 이미지를 삭제하고, Docker Hub 를 통해 새 Jar 이미지를 실행한다. uses: appleboy/ssh-action@v1.0.0 with: diff --git a/.gitignore b/.gitignore index 55608a8e..77222345 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,6 @@ build/ !gradle/wrapper/gradle-wrapper.jar !**/src/main/**/build/ !**/src/test/**/build/ -.env ### STS ### .apt_generated @@ -36,3 +35,7 @@ out/ ### VS Code ### .vscode/ + +### Secret ### +firebase-service-key.json +.env From 277c53a20a900ab577e13d2b04c3a3485937ae8e Mon Sep 17 00:00:00 2001 From: sangminnim Date: Wed, 8 Nov 2023 17:48:36 +0900 Subject: [PATCH 42/45] =?UTF-8?q?refactor:=20=EC=84=9C=EB=B8=8C=20?= =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitmodules | 4 ++-- secret => src/main/resources/secret | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename secret => src/main/resources/secret (100%) diff --git a/.gitmodules b/.gitmodules index 56d84a4f..88ae12d4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "secret"] - path = secret +[submodule "src/main/resources/secret"] + path = src/main/resources/secret url = https://github.com/coffee-meet/secret.git diff --git a/secret b/src/main/resources/secret similarity index 100% rename from secret rename to src/main/resources/secret From 46c31d40f9793014a3820f09b81b22f592f2a990 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Wed, 8 Nov 2023 17:49:46 +0900 Subject: [PATCH 43/45] =?UTF-8?q?refactor:=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/common/config/FirebaseConfig.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/common/config/FirebaseConfig.java b/src/main/java/coffeemeet/server/common/config/FirebaseConfig.java index 165aa744..6b859d62 100644 --- a/src/main/java/coffeemeet/server/common/config/FirebaseConfig.java +++ b/src/main/java/coffeemeet/server/common/config/FirebaseConfig.java @@ -14,8 +14,8 @@ public class FirebaseConfig { @Bean FirebaseApp firebaseApp() throws IOException { - String filename = "firebase-service-key.json"; - ClassPathResource resource = new ClassPathResource(filename); + String path = "secret/firebase-service-key.json"; + ClassPathResource resource = new ClassPathResource(path); FirebaseOptions options = FirebaseOptions.builder() .setCredentials(GoogleCredentials.fromStream(resource.getInputStream())).build(); From 42ae90f20992c144a89f992f60ec5743c2ecd571 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Wed, 8 Nov 2023 17:50:27 +0900 Subject: [PATCH 44/45] =?UTF-8?q?chore:=20=EC=B9=B4=ED=94=BC=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 8 -------- 1 file changed, 8 deletions(-) diff --git a/build.gradle b/build.gradle index b984d445..c1d7b7a5 100644 --- a/build.gradle +++ b/build.gradle @@ -118,14 +118,6 @@ tasks.withType(GenerateSwaggerUI) { } } -task copyPrivate(type: Copy) { - copy { - from './secret' - include "firebase-service-key.json" - into 'src/main/resources' - } -} - bootJar { dependsOn generateSwaggerUISample from("${generateSwaggerUISample.outputDir}") { From c8c04a42e3bc6b5b4c8dbfd4736a8b93b96546fa Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 8 Nov 2023 18:07:38 +0900 Subject: [PATCH 45/45] feat: update cd script --- .github/workflows/cd.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 30fd5858..2733fb07 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -9,8 +9,11 @@ jobs: test_and_deploy: runs-on: ubuntu-latest steps: - - name: 현재 작업중인 Repository 가져온다. + - name: 현재 작업중인 Repository를 서브 모듈과 함께 가져온다. uses: actions/checkout@v3 + with: + submodules: recursive + token: ${{ secrets.ACTION_TOKEN }} - name: CD 프로세스를 최적화 하기 위해 Gradle 정보를 캐싱한다. uses: actions/cache@v3