Skip to content

Commit

Permalink
Merge branch 'backend-main' into Feature/#664-행사_DTO의_imageUrl을_S3의_데…
Browse files Browse the repository at this point in the history
…이터로_대체
  • Loading branch information
amaran-th authored Oct 3, 2023
2 parents b6f4208 + 6745e1a commit 2dc704c
Show file tree
Hide file tree
Showing 17 changed files with 405 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.emmsale.event_publisher;

import com.emmsale.comment.domain.Comment;
import com.emmsale.member.domain.Member;
import java.time.LocalDateTime;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Getter
public class CommentNotificationEvent {

private static final String UPDATE_NOTIFICATION_COMMENT_TYPE = "COMMENT";

private final Long receiverId;
private final Long redirectId;
private final LocalDateTime createdAt;
private final String notificationType;
private final String content;
private final String writer;
private final String writerImageUrl;

public static CommentNotificationEvent of(final Comment comment, final Comment trigger) {
final Member member = comment.getMember();
final Member triggerMember = trigger.getMember();

return new CommentNotificationEvent(
member.getId(),
trigger.getId(),
LocalDateTime.now(),
UPDATE_NOTIFICATION_COMMENT_TYPE,
trigger.getContent(),
triggerMember.getName(),
triggerMember.getImageUrl()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.emmsale.event_publisher;

import com.emmsale.event.domain.Event;
import java.time.LocalDateTime;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Getter
public class EventNotificationEvent {

private static final String UPDATE_NOTIFICATION_EVENT_TYPE = "EVENT";

private final Long receiverId;
private final Long redirectId;
private final String notificationType;
private final LocalDateTime createdAt;
private final String title;

public static EventNotificationEvent of(final Event event, final Long receiverId) {
return new EventNotificationEvent(
receiverId,
event.getId(),
UPDATE_NOTIFICATION_EVENT_TYPE,
LocalDateTime.now(),
event.getName()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public void publish(final Comment trigger, final Member loginMember) {
.orElse(Collections.emptySet());

notificationCommentCandidates.stream()
.map(it -> UpdateNotificationEvent.of(it, trigger.getId()))
.map(it -> CommentNotificationEvent.of(it, trigger))
.forEach(applicationEventPublisher::publishEvent);
}

Expand Down Expand Up @@ -71,7 +71,7 @@ public void publish(final Event event) {
private void publishEvent(final Event event, final List<Member> members) {
members.forEach(
it -> applicationEventPublisher.publishEvent(
UpdateNotificationEvent.of(event, it.getId())
EventNotificationEvent.of(event, it.getId())
)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,25 @@

import com.emmsale.event_publisher.MessageNotificationEvent;
import com.emmsale.member.domain.MemberRepository;
import com.emmsale.notification.application.generator.CommentNotificationMessageGenerator;
import com.emmsale.notification.application.generator.EventNotificationMessageGenerator;
import com.emmsale.notification.application.generator.MessageNotificationMessageGenerator;
import com.emmsale.notification.application.generator.NotificationMessageGenerator;
import com.emmsale.notification.application.generator.RequestNotificationMessageGenerator;
import com.emmsale.notification.application.generator.UpdateNotificationMessageGenerator;
import com.emmsale.notification.domain.FcmToken;
import com.emmsale.notification.domain.FcmTokenRepository;
import com.emmsale.notification.domain.Notification;
import com.emmsale.notification.domain.NotificationType;
import com.emmsale.notification.domain.RequestNotification;
import com.emmsale.notification.domain.UpdateNotification;
import com.emmsale.notification.exception.NotificationException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
Expand All @@ -41,6 +47,12 @@ public class FirebaseCloudMessageClient {
private static final String POSTFIX_FCM_REQUEST_URL = "/messages:send";
private static final String FIREBASE_KEY_PATH = "kerdy-submodule/firebase-kerdy.json";
private static final String GOOGLE_AUTH_URL = "https://www.googleapis.com/auth/cloud-platform";
private static final Map<NotificationType, Function<Notification, NotificationMessageGenerator>> GENERATOR_MAP =
Map.of(
NotificationType.EVENT, EventNotificationMessageGenerator::new,
NotificationType.COMMENT, CommentNotificationMessageGenerator::new
);


private final ObjectMapper objectMapper;
private final MemberRepository memberRepository;
Expand Down Expand Up @@ -71,6 +83,13 @@ public void sendMessageTo(final MessageNotificationEvent messageNotificationEven
);
}

public void sendMessageTo(final Notification notification, final Long receiverId) {
sendMessageTo(
receiverId,
GENERATOR_MAP.get(notification.getType()).apply(notification)
);
}

private void sendMessageTo(
final Long receiverId,
final NotificationMessageGenerator messageGenerator
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
package com.emmsale.notification.application;

import com.emmsale.event_publisher.CommentNotificationEvent;
import com.emmsale.event_publisher.EventNotificationEvent;
import com.emmsale.event_publisher.MessageNotificationEvent;
import com.emmsale.event_publisher.UpdateNotificationEvent;
import com.emmsale.notification.domain.Notification;
import com.emmsale.notification.domain.NotificationRepository;
import com.emmsale.notification.domain.NotificationType;
import com.emmsale.notification.domain.UpdateNotification;
import com.emmsale.notification.domain.UpdateNotificationRepository;
import com.emmsale.notification.domain.UpdateNotificationType;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
Expand All @@ -19,6 +26,8 @@ public class NotificationEventListener {

private final UpdateNotificationRepository updateNotificationRepository;
private final FirebaseCloudMessageClient firebaseCloudMessageClient;
private final NotificationRepository notificationRepository;
private final ObjectMapper objectMapper;

@Transactional(propagation = Propagation.REQUIRES_NEW)
@TransactionalEventListener
Expand All @@ -40,6 +49,50 @@ public void createUpdateNotification(final UpdateNotificationEvent updateNotific
}
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
@TransactionalEventListener
public void createCommentNotification(final CommentNotificationEvent commentNotificationEvent) {
try {
final String jsonData = objectMapper.writeValueAsString(commentNotificationEvent);

final Notification notification = notificationRepository.save(
new Notification(NotificationType.COMMENT, jsonData)
);

firebaseCloudMessageClient.sendMessageTo(
notification,
commentNotificationEvent.getReceiverId()
);

} catch (JsonProcessingException e) {
log.error("json 에러");
} catch (Exception e) {
log.error("파이어베이스 관련 에러, 알림 재요청 필요, {}", e.getMessage(), e);
}
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
@TransactionalEventListener
public void createEventNotification(final EventNotificationEvent eventNotificationEvent) {
try {
final String jsonData = objectMapper.writeValueAsString(eventNotificationEvent);

final Notification notification = notificationRepository.save(
new Notification(NotificationType.EVENT, jsonData)
);

firebaseCloudMessageClient.sendMessageTo(
notification,
eventNotificationEvent.getReceiverId()
);

} catch (JsonProcessingException e) {
log.error("json 에러");
} catch (Exception e) {
log.error("파이어베이스 관련 에러, 알림 재요청 필요, {}", e.getMessage(), e);
}
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
@TransactionalEventListener
public void createMessageNotification(final MessageNotificationEvent messageNotificationEvent) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.emmsale.notification.application.dto;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Getter
public class CommentNotificationMessage {

@JsonProperty("validate_only")
private final boolean validateOnly;
private final Message message;

@RequiredArgsConstructor
@Getter
public static class Message {

private final Data data;
private final String token;
}

@RequiredArgsConstructor
@Getter
public static class Data {

private final String receiverId;
private final String redirectId;
private final String notificationType;
private final String createdAt;
private final String content;
private final String writer;
private final String writerImageUrl;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.emmsale.notification.application.dto;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Getter
public class EventNotificationMessage {

@JsonProperty("validate_only")
private final boolean validateOnly;
private final Message message;

@RequiredArgsConstructor
@Getter
public static class Message {

private final Data data;
private final String token;
}

@RequiredArgsConstructor
@Getter
public static class Data {

private final String receiverId;
private final String redirectId;
private final String notificationType;
private final String createdAt;
private final String title;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.emmsale.notification.application.generator;

import static com.emmsale.notification.exception.NotificationExceptionType.BAD_REQUEST_MEMBER_ID;
import static com.emmsale.notification.exception.NotificationExceptionType.CONVERTING_JSON_ERROR;

import com.emmsale.member.domain.MemberRepository;
import com.emmsale.notification.application.dto.CommentNotificationMessage;
import com.emmsale.notification.application.dto.CommentNotificationMessage.Data;
import com.emmsale.notification.application.dto.CommentNotificationMessage.Message;
import com.emmsale.notification.domain.Notification;
import com.emmsale.notification.exception.NotificationException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class CommentNotificationMessageGenerator implements NotificationMessageGenerator {

private final Notification notification;

@Override
public String makeMessage(
final String targetToken,
final ObjectMapper objectMapper,
final MemberRepository memberRepository
) {

final String jsonData = notification.getJsonData();

try {

final Data data = objectMapper.readValue(jsonData, Data.class);

validateIsExistedReceiver(memberRepository, Long.valueOf(data.getReceiverId()));

final CommentNotificationMessage message = new CommentNotificationMessage(
DEFAULT_VALIDATE_ONLY, new Message(data, targetToken)
);

return objectMapper.writeValueAsString(message);

} catch (JsonProcessingException e) {
throw new NotificationException(CONVERTING_JSON_ERROR);
}
}

private void validateIsExistedReceiver(final MemberRepository memberRepository,
final Long receiverId) {
if (!memberRepository.existsById(receiverId)) {
throw new NotificationException(BAD_REQUEST_MEMBER_ID);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.emmsale.notification.application.generator;

import static com.emmsale.notification.application.dto.EventNotificationMessage.Data;
import static com.emmsale.notification.exception.NotificationExceptionType.BAD_REQUEST_MEMBER_ID;
import static com.emmsale.notification.exception.NotificationExceptionType.CONVERTING_JSON_ERROR;

import com.emmsale.member.domain.MemberRepository;
import com.emmsale.notification.application.dto.EventNotificationMessage;
import com.emmsale.notification.application.dto.EventNotificationMessage.Message;
import com.emmsale.notification.domain.Notification;
import com.emmsale.notification.exception.NotificationException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class EventNotificationMessageGenerator implements NotificationMessageGenerator {

private final Notification notification;

@Override
public String makeMessage(
final String targetToken,
final ObjectMapper objectMapper,
final MemberRepository memberRepository
) {
final String jsonData = notification.getJsonData();

try {

final Data data = objectMapper.readValue(jsonData, Data.class);

validateIsExistedReceiver(memberRepository, Long.valueOf(data.getReceiverId()));

final EventNotificationMessage message = new EventNotificationMessage(
DEFAULT_VALIDATE_ONLY, new Message(data, targetToken)
);

return objectMapper.writeValueAsString(message);

} catch (JsonProcessingException e) {
throw new NotificationException(CONVERTING_JSON_ERROR);
}
}

private void validateIsExistedReceiver(final MemberRepository memberRepository,
final Long receiverId) {
if (!memberRepository.existsById(receiverId)) {
throw new NotificationException(BAD_REQUEST_MEMBER_ID);
}
}
}
Loading

0 comments on commit 2dc704c

Please sign in to comment.