feat(order, notification, kafka): 주문 상태 변경 시 kafka 메시지 발송
This commit is contained in:
@@ -34,6 +34,17 @@ public class NotificationConsumer {
|
|||||||
notificationService.insertOrderPlaced(kafkaSendOrderDto.getUserId(), kafkaSendOrderDto.getStoreId());
|
notificationService.insertOrderPlaced(kafkaSendOrderDto.getUserId(), kafkaSendOrderDto.getStoreId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@KafkaListener(topics = "orderAccepted")
|
||||||
|
public void orderAccepted(String kafkaMessage) throws JsonProcessingException {
|
||||||
|
log.debug("## NotificationConsumer.orderAccepted");
|
||||||
|
log.debug("#### kafka Message = {}", kafkaMessage);
|
||||||
|
|
||||||
|
KafkaSendOrderDto orderDto = objectMapper.readValue(kafkaMessage, KafkaSendOrderDto.class);
|
||||||
|
|
||||||
|
notificationService.insertOrderAccepted(orderDto.userId, orderDto.storeId);
|
||||||
|
}
|
||||||
|
|
||||||
@Data @NoArgsConstructor
|
@Data @NoArgsConstructor
|
||||||
static class KafkaSendOrderDto {
|
static class KafkaSendOrderDto {
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|||||||
@@ -11,4 +11,5 @@ public interface NotificationService {
|
|||||||
void updateNotification(UpdateNotificationDto dto);
|
void updateNotification(UpdateNotificationDto dto);
|
||||||
Long findNotificationCounts(Long userId, Yn readYn);
|
Long findNotificationCounts(Long userId, Yn readYn);
|
||||||
void insertOrderPlaced(Long userId, Long storeId);
|
void insertOrderPlaced(Long userId, Long storeId);
|
||||||
|
void insertOrderAccepted(Long userId, Long storeId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,9 +59,22 @@ public class NotificationServiceImpl implements NotificationService {
|
|||||||
GetStoreResponse storeResponse = storeClient.getStore(String.valueOf(storeId)).getData();
|
GetStoreResponse storeResponse = storeClient.getStore(String.valueOf(storeId)).getData();
|
||||||
|
|
||||||
String title = "주문이 신청되었어요.";
|
String title = "주문이 신청되었어요.";
|
||||||
String storeName = "[" + storeResponse.getName() + "]";
|
String storeName = "[" + storeResponse.getName() + "] ";
|
||||||
String message = storeName + "매장의 주문이 신청되었습니다.";
|
String message = storeName + "매장의 주문이 신청되었습니다.";
|
||||||
Notification notification = Notification.of(userId, message, title);
|
Notification notification = Notification.of(userId, message, title);
|
||||||
notificationRepository.save(notification);
|
notificationRepository.save(notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public void insertOrderAccepted(Long userId, Long storeId) {
|
||||||
|
GetStoreResponse storeInfo = storeClient.getStore(String.valueOf(storeId)).getData();
|
||||||
|
|
||||||
|
String title = "주문이 수락되었어요.";
|
||||||
|
String storeName = "[" + storeInfo.getName() + "] ";
|
||||||
|
String message = storeName + "매장의 주문이 수락되었습니다.";
|
||||||
|
Notification notification = Notification.of(userId, message, title);
|
||||||
|
notificationRepository.save(notification);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,21 +15,24 @@ public class OrderListener {
|
|||||||
@Lazy
|
@Lazy
|
||||||
private OrderSender orderSender;
|
private OrderSender orderSender;
|
||||||
|
|
||||||
|
|
||||||
// TODO: 2022/03/15 exception 발생시 order fail 처리
|
// TODO: 2022/03/15 exception 발생시 order fail 처리
|
||||||
@PostUpdate
|
@PostUpdate
|
||||||
public void postUpdate(Order order){
|
public void postUpdate(Order order){
|
||||||
OrderStatus orderStatus = order.getOrderStatus();
|
OrderStatus orderStatus = order.getOrderStatus();
|
||||||
|
log.info("[OrderListener] {}", OrderStatus.PLACED.name());
|
||||||
if (orderStatus == OrderStatus.PLACED) {
|
if (orderStatus == OrderStatus.PLACED) {
|
||||||
log.info("[OrderListener] {}", OrderStatus.PLACED.name());
|
|
||||||
try{
|
try{
|
||||||
orderSender.orderPlaced(OrderSender.KafkaSendOrderDto.createPrimitiveField(order));
|
orderSender.orderPlaced(order);
|
||||||
}catch (Exception ex){
|
}catch (Exception ex){
|
||||||
throw new OrderException(ex.getMessage());
|
throw new OrderException(ex.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (orderStatus == OrderStatus.ACCEPTED) {
|
} else if (orderStatus == OrderStatus.ACCEPTED) {
|
||||||
log.info("[OrderListener] {}", OrderStatus.ACCEPTED.name());
|
try {
|
||||||
|
orderSender.orderAccepted(order);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new OrderException(ex.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public class OrderRepositoryCustom {
|
|||||||
|
|
||||||
List<Order> orders = queryFactory
|
List<Order> orders = queryFactory
|
||||||
.selectFrom(order)
|
.selectFrom(order)
|
||||||
.leftJoin(order.transaction)
|
.leftJoin(order.transaction).fetchJoin()
|
||||||
.where(
|
.where(
|
||||||
orderIdLt(condition.getLastOrderId()),
|
orderIdLt(condition.getLastOrderId()),
|
||||||
order.orderTime.between(start, end),
|
order.orderTime.between(start, end),
|
||||||
|
|||||||
@@ -19,19 +19,31 @@ import java.util.List;
|
|||||||
public class OrderSender {
|
public class OrderSender {
|
||||||
|
|
||||||
private final KafkaTemplate<String, String> kafkaTemplate;
|
private final KafkaTemplate<String, String> kafkaTemplate;
|
||||||
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
public void orderPlaced( KafkaSendOrderDto kafkaSendOrderDto) throws Exception{
|
public void orderPlaced(Order order) throws Exception{
|
||||||
ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());
|
objectMapper.registerModule(new JavaTimeModule());
|
||||||
String jsonInString = mapper.writeValueAsString(kafkaSendOrderDto);
|
|
||||||
|
KafkaSendOrderDto kafkaSendOrderDto = KafkaSendOrderDto.createPrimitiveField(order);
|
||||||
|
String jsonInString = objectMapper.writeValueAsString(kafkaSendOrderDto);
|
||||||
kafkaTemplate.send("orderPlaced", jsonInString);
|
kafkaTemplate.send("orderPlaced", jsonInString);
|
||||||
log.info("kafka Producer sent data from the Order microservice: "+ kafkaSendOrderDto);
|
log.info("kafka Producer sent data from the Order microservice: "+ kafkaSendOrderDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void orderAccepted(Order order) throws Exception {
|
||||||
|
objectMapper.registerModule(new JavaTimeModule());
|
||||||
|
|
||||||
|
KafkaSendOrderDto kafkaSendOrderDto = KafkaSendOrderDto.createPrimitiveField(order);
|
||||||
|
String json = objectMapper.writeValueAsString(kafkaSendOrderDto);
|
||||||
|
kafkaTemplate.send("orderAccepted", json);
|
||||||
|
log.info("[OrderSender] orderAccepted = {}", json);
|
||||||
|
}
|
||||||
|
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@Builder
|
@Builder
|
||||||
public static class KafkaSendOrderDto{
|
public static class KafkaSendOrderDto {
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
private Long userId;
|
private Long userId;
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ public interface StoreClient {
|
|||||||
Result<List<GetItemResponse>> getItemAndItemOptions(@PathVariable(value = "itemId") Iterable<Long> itemIds);
|
Result<List<GetItemResponse>> getItemAndItemOptions(@PathVariable(value = "itemId") Iterable<Long> itemIds);
|
||||||
|
|
||||||
default Map<Long, String> getStoreNameMap(Set<Long> storeIds) {
|
default Map<Long, String> getStoreNameMap(Set<Long> storeIds) {
|
||||||
|
if (!storeIds.iterator().hasNext()) return null;
|
||||||
List<GetStoreResponse> storeResponses = this.getStoreAllById(storeIds).getData();
|
List<GetStoreResponse> storeResponses = this.getStoreAllById(storeIds).getData();
|
||||||
return storeResponses.stream()
|
return storeResponses.stream()
|
||||||
.collect(
|
.collect(
|
||||||
@@ -43,6 +44,7 @@ public interface StoreClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
default Map<Long, String> getItemNameMap(Iterable<Long> itemIds) {
|
default Map<Long, String> getItemNameMap(Iterable<Long> itemIds) {
|
||||||
|
if (!itemIds.iterator().hasNext()) return null;
|
||||||
List<GetItemsResponse> itemResponses = this.getItems(itemIds).getData();
|
List<GetItemsResponse> itemResponses = this.getItems(itemIds).getData();
|
||||||
return itemResponses.stream()
|
return itemResponses.stream()
|
||||||
.collect(
|
.collect(
|
||||||
@@ -51,6 +53,7 @@ public interface StoreClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
default Map<Long, GetItemResponse> getItemAndItemOptionMap(Iterable<Long> itemIds) {
|
default Map<Long, GetItemResponse> getItemAndItemOptionMap(Iterable<Long> itemIds) {
|
||||||
|
if (!itemIds.iterator().hasNext()) return null;
|
||||||
List<GetItemResponse> responses = this.getItemAndItemOptions(itemIds).getData();
|
List<GetItemResponse> responses = this.getItemAndItemOptions(itemIds).getData();
|
||||||
return responses.stream()
|
return responses.stream()
|
||||||
.collect(
|
.collect(
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public interface UserClient {
|
|||||||
Result<List<GetCustomerResponse>> getCustomers(@PathVariable("userIds") Iterable<Long> userIds);
|
Result<List<GetCustomerResponse>> getCustomers(@PathVariable("userIds") Iterable<Long> userIds);
|
||||||
|
|
||||||
default Map<Long, String> getUserNameMap(Iterable<Long> userIds) {
|
default Map<Long, String> getUserNameMap(Iterable<Long> userIds) {
|
||||||
|
if (!userIds.iterator().hasNext()) return null;
|
||||||
List<GetCustomerResponse> userResponses = this.getCustomers(userIds).getData();
|
List<GetCustomerResponse> userResponses = this.getCustomers(userIds).getData();
|
||||||
return userResponses.stream()
|
return userResponses.stream()
|
||||||
.collect(
|
.collect(
|
||||||
|
|||||||
@@ -101,6 +101,8 @@ class OrderControllerTest {
|
|||||||
fieldWithPath("code").description("결과코드 SUCCESS/ERROR"),
|
fieldWithPath("code").description("결과코드 SUCCESS/ERROR"),
|
||||||
fieldWithPath("message").description("메세지"),
|
fieldWithPath("message").description("메세지"),
|
||||||
fieldWithPath("data.id").description("주문 고유번호"),
|
fieldWithPath("data.id").description("주문 고유번호"),
|
||||||
|
fieldWithPath("data.storeName").description("주문 매장이름"),
|
||||||
|
fieldWithPath("data.orderStatus").description("주문 상태"),
|
||||||
fieldWithPath("data.orderTime").description("주문 시간 [yyy-MM-dd]"),
|
fieldWithPath("data.orderTime").description("주문 시간 [yyy-MM-dd]"),
|
||||||
fieldWithPath("data.orderPrice").description("주문 금액"),
|
fieldWithPath("data.orderPrice").description("주문 금액"),
|
||||||
fieldWithPath("data.user.id").description("주문한 회원 고유번호"),
|
fieldWithPath("data.user.id").description("주문한 회원 고유번호"),
|
||||||
@@ -168,7 +170,9 @@ class OrderControllerTest {
|
|||||||
|
|
||||||
return OrderDetailDto.builder()
|
return OrderDetailDto.builder()
|
||||||
.id(orderId)
|
.id(orderId)
|
||||||
|
.orderStatus(OrderStatus.PLACED)
|
||||||
.orderTime(LocalDateTime.now())
|
.orderTime(LocalDateTime.now())
|
||||||
|
.storeName("매장이름")
|
||||||
.orderPrice(76600L)
|
.orderPrice(76600L)
|
||||||
.user(orderDetailUser)
|
.user(orderDetailUser)
|
||||||
.orderItems(List.of(카페라떼, 아메리카노))
|
.orderItems(List.of(카페라떼, 아메리카노))
|
||||||
|
|||||||
Reference in New Issue
Block a user