Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ LF1-674 신규 주문 알림 sse #11

Merged
merged 2 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package kr.bb.notification.domain.emitter.api;

import com.fasterxml.jackson.core.JsonProcessingException;
import kr.bb.notification.domain.emitter.application.SseService;
import kr.bb.notification.domain.notification.entity.NotificationCommand.SSENotification;
import kr.bb.notification.domain.notification.infrastructure.message.SQSPublishTest;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
Expand All @@ -13,6 +16,7 @@
@RequiredArgsConstructor
public class SSEClientController {
private final SseService sseService;
private final SQSPublishTest sqsPublishTest;

// TODO: 삭제될 예정, sse 전송 테스트 용
@PostMapping(value = "/send-data/manager/{userId}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
Expand All @@ -26,4 +30,9 @@ public void sendData(@PathVariable Long userId, @RequestBody String data) {
.build();
sseService.notify(build);
}

@GetMapping("sqs-test")
public void sqsTest() throws JsonProcessingException {
sqsPublishTest.sqsSend();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,14 @@ public class SSERestController {
public SseEmitter subscribeManager(@PathVariable Long userId) {
return sseService.subscribe(userId, "manager");
}

@GetMapping(value = "subscribe/admin/{userId}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter subscribeAdmin(@PathVariable Long userId) {
return sseService.subscribe(userId, "admin");
}

@GetMapping(value = "subscribe/customer/{userId}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter subscribe(@PathVariable Long userId) {
return sseService.subscribe(userId, "customer");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,27 @@
import kr.bb.notification.domain.notification.entity.MemberNotificationCommand;
import kr.bb.notification.domain.notification.entity.Notification;
import kr.bb.notification.domain.notification.entity.NotificationCommand;
import kr.bb.notification.domain.notification.infrastructure.dto.NewOrderNotification;
import kr.bb.notification.domain.notification.repository.NotificationJpaRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
@RequiredArgsConstructor
public class NotificationCommandService {
private final NotificationJpaRepository notificationJpaRepository;

@Transactional
public void saveResaleNotification(NotificationData<ResaleNotificationList> restoreNotification) {
Notification notification = NotificationCommand.toEntity(restoreNotification.getPublishInformation());
Notification notification =
NotificationCommand.toEntity(restoreNotification.getPublishInformation());
List<MemberNotification> memberNotifications =
MemberNotificationCommand.toEntityList(restoreNotification.getWhoToNotify());
notification.setMemberNotifications(memberNotifications);
notificationJpaRepository.save(notification);
}

@Transactional
public void saveQuestionRegister(
NotificationData<QuestionRegisterNotification> questionRegisterNotification) {
Notification notification =
Expand All @@ -37,4 +38,14 @@ public void saveQuestionRegister(
notification.setMemberNotifications(List.of(memberNotification));
notificationJpaRepository.save(notification);
}

public void saveNewOrderNotification(
NotificationData<NewOrderNotification> newOrderNotification) {
Notification notification =
NotificationCommand.toEntity(newOrderNotification.getPublishInformation());
MemberNotification entityForStoreManager =
MemberNotificationCommand.toEntityForStoreManager(newOrderNotification.getWhoToNotify());
notification.setMemberNotifications(List.of(entityForStoreManager));
notificationJpaRepository.save(notification);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import bloomingblooms.domain.resale.ResaleNotificationList;
import java.util.List;
import java.util.stream.Collectors;
import kr.bb.notification.domain.notification.infrastructure.dto.NewOrderNotification;

public class MemberNotificationCommand {

Expand All @@ -16,4 +17,8 @@ public static List<MemberNotification> toEntityList(ResaleNotificationList whoTo
public static MemberNotification toEntity(QuestionRegisterNotification whoToNotify) {
return MemberNotification.builder().userId(whoToNotify.getUserId()).build();
}

public static MemberNotification toEntityForStoreManager(NewOrderNotification whoToNotify) {
return MemberNotification.builder().userId(whoToNotify.getStoreId()).build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import bloomingblooms.domain.notification.NotificationData;
import bloomingblooms.domain.notification.PublishNotificationInformation;
import bloomingblooms.domain.notification.QuestionRegisterNotification;
import bloomingblooms.domain.notification.Role;
import bloomingblooms.domain.resale.ResaleNotificationList;
import java.util.List;
import java.util.stream.Collectors;
import kr.bb.notification.domain.notification.infrastructure.dto.NewOrderNotification;
import lombok.Builder;
import lombok.Getter;

Expand Down Expand Up @@ -158,6 +160,21 @@ public static SSENotification getQuestionRegisterSSEData(
.build();
}

public static SSENotification getNewOrderNotification(
NotificationData<NewOrderNotification> newOrderNotification) {
return SSENotification.builder()
.role(Role.MANAGER.getRole())
.content(
newOrderNotification.getPublishInformation().getNotificationKind().getKind()
+ "\n"
+ newOrderNotification.getWhoToNotify().getOrderType().getOrderType()
+ ": "
+ newOrderNotification.getPublishInformation().getMessage())
.redirectUrl(newOrderNotification.getPublishInformation().getNotificationUrl())
.userId(newOrderNotification.getWhoToNotify().getStoreId())
.build();
}

public static class SSENotificationBuilder extends NotificationInformationBuilder {
@Override
public SSENotification build() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import kr.bb.notification.domain.notification.application.NotificationCommandService;
import kr.bb.notification.domain.notification.entity.NotificationCommand.SMSNotification;
import kr.bb.notification.domain.notification.entity.NotificationCommand.SSENotification;
import kr.bb.notification.domain.notification.infrastructure.dto.NewOrderNotification;
import kr.bb.notification.domain.notification.infrastructure.sms.SendSMS;
import kr.bb.notification.domain.notification.infrastructure.sse.SendSSE;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -37,4 +38,13 @@ public void publishQuestionRegisterNotification(
// save notification
notificationCommandService.saveQuestionRegister(questionRegisterNotification);
}

public void publishNewOrderNotification(
NotificationData<NewOrderNotification> newOrderNotification) {
SSENotification sseNotification = SSENotification.getNewOrderNotification(newOrderNotification);
sse.publishCustomer(sseNotification);

// save notification
notificationCommandService.saveNewOrderNotification(newOrderNotification);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package kr.bb.notification.domain.notification.infrastructure.dto;

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class NewOrderNotification {
private String productName;
private Long storeId;
private OrderType orderType;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package kr.bb.notification.domain.notification.infrastructure.dto;

import lombok.Getter;

@Getter
public enum OrderType {
PICKUP("픽업"),
SUBSCRIBE("구독"),
DELIVERY("배송");
private final String orderType;

OrderType(String orderType) {
this.orderType = orderType;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
import kr.bb.notification.domain.notification.facade.NotificationFacadeHandler;
import kr.bb.notification.domain.notification.infrastructure.dto.NewOrderNotification;
import lombok.RequiredArgsConstructor;
import org.springframework.cloud.aws.messaging.listener.Acknowledgment;
import org.springframework.cloud.aws.messaging.listener.SqsMessageDeletionPolicy;
Expand Down Expand Up @@ -55,4 +56,21 @@ public void consumeQuestionRegisterNotificationQueue(
notificationFacadeHandler.publishQuestionRegisterNotification(questionRegisterNotification);
ack.acknowledge();
}

@SqsListener(
value = "${cloud.aws.sqs.new-order-queue.name}",
deletionPolicy = SqsMessageDeletionPolicy.NEVER)
public void consumeNewOrderNotificationQueue(
@Payload String message, @Headers Map<String, String> headers, Acknowledgment ack)
throws JsonProcessingException {
NotificationData<NewOrderNotification> newOrderNotification =
objectMapper.readValue(
message,
objectMapper
.getTypeFactory()
.constructParametricType(NotificationData.class, NewOrderNotification.class));
// call facade
notificationFacadeHandler.publishNewOrderNotification(newOrderNotification);
ack.acknowledge();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package kr.bb.notification.domain.notification.infrastructure.message;

import bloomingblooms.domain.notification.NotificationData;
import bloomingblooms.domain.notification.NotificationKind;
import bloomingblooms.domain.notification.PublishNotificationInformation;
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.model.SendMessageRequest;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import kr.bb.notification.domain.notification.infrastructure.dto.NewOrderNotification;
import kr.bb.notification.domain.notification.infrastructure.dto.OrderType;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class SQSPublishTest {
private final AmazonSQS sqs;
private final ObjectMapper objectMapper;

@Value("${cloud.aws.sqs.new-order-queue.url}")
private String newOrder;

public void sqsSend() throws JsonProcessingException {
NewOrderNotification build =
NewOrderNotification.builder()
.orderType(OrderType.SUBSCRIBE)
.productName("장미 꽃다발")
.storeId(1L)
.build();

SendMessageRequest sendMessageRequest =
new SendMessageRequest(
newOrder,
objectMapper.writeValueAsString(
NotificationData.builder()
.whoToNotify(build)
.publishInformation(
PublishNotificationInformation.builder()
.message(build.getProductName() + " 상품이 주문되었습니다")
.notificationUrl("/orders/" + build.getStoreId())
.notificationKind(NotificationKind.NEW_ORDER)
.build())
.build()));
sqs.sendMessage(sendMessageRequest);
}
}
3 changes: 3 additions & 0 deletions src/test/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,6 @@ cloud:
question-register-notification-queue:
name: ""
url: ""
new-order-queue:
name: ""
url: ""
Loading