Outbox Message and Scheduler class implemented part - 3.
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
package com.food.order.sysyem;
|
||||
package com.food.order.system;
|
||||
|
||||
import com.food.order.sysyem.dto.create.CreateOrderCommand;
|
||||
import com.food.order.sysyem.dto.create.CreateOrderResponse;
|
||||
import com.food.order.sysyem.dto.track.TrackOrderQuery;
|
||||
import com.food.order.sysyem.dto.track.TrackOrderResponse;
|
||||
import com.food.order.sysyem.ports.input.service.OrderApplicationService;
|
||||
import com.food.order.system.dto.create.CreateOrderCommand;
|
||||
import com.food.order.system.dto.create.CreateOrderResponse;
|
||||
import com.food.order.system.dto.track.TrackOrderQuery;
|
||||
import com.food.order.system.dto.track.TrackOrderResponse;
|
||||
import com.food.order.system.ports.input.service.OrderApplicationService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -1,12 +1,12 @@
|
||||
package com.food.order.sysyem;
|
||||
package com.food.order.system;
|
||||
|
||||
import com.food.order.system.dto.create.CreateOrderCommand;
|
||||
import com.food.order.system.dto.create.CreateOrderResponse;
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.sysyem.dto.create.CreateOrderCommand;
|
||||
import com.food.order.sysyem.dto.create.CreateOrderResponse;
|
||||
import com.food.order.sysyem.helper.OrderCreateHelper;
|
||||
import com.food.order.sysyem.helper.OrderSagaHelper;
|
||||
import com.food.order.sysyem.mapper.OrderDataMapper;
|
||||
import com.food.order.sysyem.outbox.scheduler.payment.PaymentOutboxHelper;
|
||||
import com.food.order.system.helper.OrderCreateHelper;
|
||||
import com.food.order.system.helper.OrderSagaHelper;
|
||||
import com.food.order.system.mapper.OrderDataMapper;
|
||||
import com.food.order.system.outbox.scheduler.payment.PaymentOutboxHelper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.food.order.sysyem;
|
||||
package com.food.order.system;
|
||||
|
||||
import com.food.order.sysyem.dto.track.TrackOrderQuery;
|
||||
import com.food.order.sysyem.dto.track.TrackOrderResponse;
|
||||
import com.food.order.sysyem.mapper.OrderDataMapper;
|
||||
import com.food.order.sysyem.ports.output.repository.OrderRepository;
|
||||
import com.food.order.system.dto.track.TrackOrderQuery;
|
||||
import com.food.order.system.dto.track.TrackOrderResponse;
|
||||
import com.food.order.system.mapper.OrderDataMapper;
|
||||
import com.food.order.system.ports.output.repository.OrderRepository;
|
||||
import com.food.order.system.domain.exception.OrderNotFoundException;
|
||||
import com.food.order.system.domain.valueobject.TrackingId;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.food.order.sysyem;
|
||||
package com.food.order.system;
|
||||
|
||||
import com.food.order.sysyem.dto.message.PaymentResponse;
|
||||
import com.food.order.sysyem.ports.input.message.listener.payment.PaymentResponseMessageListener;
|
||||
import com.food.order.sysyem.saga.OrderPaymentSaga;
|
||||
import com.food.order.system.dto.message.PaymentResponse;
|
||||
import com.food.order.system.ports.input.message.listener.payment.PaymentResponseMessageListener;
|
||||
import com.food.order.system.saga.OrderPaymentSaga;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.food.order.sysyem;
|
||||
package com.food.order.system;
|
||||
|
||||
import com.food.order.sysyem.dto.message.RestaurantApprovalResponse;
|
||||
import com.food.order.sysyem.ports.input.message.listener.restaurantapproval.RestaurantApprovalResponseMessageListener;
|
||||
import com.food.order.sysyem.saga.OrderApprovalSaga;
|
||||
import com.food.order.system.dto.message.RestaurantApprovalResponse;
|
||||
import com.food.order.system.ports.input.message.listener.restaurantapproval.RestaurantApprovalResponseMessageListener;
|
||||
import com.food.order.system.saga.OrderApprovalSaga;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.food.order.sysyem.config;
|
||||
package com.food.order.system.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.food.order.sysyem.dto.create;
|
||||
package com.food.order.system.dto.create;
|
||||
|
||||
import lombok.Builder;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.food.order.sysyem.dto.create;
|
||||
package com.food.order.system.dto.create;
|
||||
|
||||
import com.food.order.sysyem.valueobject.OrderStatus;
|
||||
import com.food.order.system.valueobject.OrderStatus;
|
||||
import lombok.Builder;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.food.order.sysyem.dto.create;
|
||||
package com.food.order.system.dto.create;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.food.order.sysyem.dto.create;
|
||||
package com.food.order.system.dto.create;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.food.order.sysyem.dto.message;
|
||||
package com.food.order.system.dto.message;
|
||||
|
||||
import com.food.order.sysyem.valueobject.PaymentStatus;
|
||||
import com.food.order.system.valueobject.PaymentStatus;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.food.order.sysyem.dto.message;
|
||||
package com.food.order.system.dto.message;
|
||||
|
||||
import com.food.order.sysyem.valueobject.OrderApprovalStatus;
|
||||
import com.food.order.system.valueobject.OrderApprovalStatus;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.food.order.sysyem.dto.track;
|
||||
package com.food.order.system.dto.track;
|
||||
|
||||
import lombok.Builder;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.food.order.sysyem.dto.track;
|
||||
package com.food.order.system.dto.track;
|
||||
|
||||
import com.food.order.sysyem.valueobject.OrderStatus;
|
||||
import com.food.order.system.valueobject.OrderStatus;
|
||||
import lombok.Builder;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
@@ -1,11 +1,10 @@
|
||||
package com.food.order.sysyem.helper;
|
||||
package com.food.order.system.helper;
|
||||
|
||||
import com.food.order.sysyem.dto.create.CreateOrderCommand;
|
||||
import com.food.order.sysyem.event.publisher.DomainEventPublisher;
|
||||
import com.food.order.sysyem.mapper.OrderDataMapper;
|
||||
import com.food.order.sysyem.ports.output.repository.CustomerRepository;
|
||||
import com.food.order.sysyem.ports.output.repository.OrderRepository;
|
||||
import com.food.order.sysyem.ports.output.repository.RestaurantRepository;
|
||||
import com.food.order.system.dto.create.CreateOrderCommand;
|
||||
import com.food.order.system.mapper.OrderDataMapper;
|
||||
import com.food.order.system.ports.output.repository.CustomerRepository;
|
||||
import com.food.order.system.ports.output.repository.OrderRepository;
|
||||
import com.food.order.system.ports.output.repository.RestaurantRepository;
|
||||
import com.food.order.system.domain.entity.Order;
|
||||
import com.food.order.system.domain.entity.Restaurant;
|
||||
import com.food.order.system.domain.event.OrderCreatedEvent;
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.food.order.sysyem.helper;
|
||||
package com.food.order.system.helper;
|
||||
|
||||
import com.food.order.system.domain.entity.Order;
|
||||
import com.food.order.system.domain.exception.OrderNotFoundException;
|
||||
import com.food.order.system.ports.output.repository.OrderRepository;
|
||||
import com.food.order.system.saga.SagaStatus;
|
||||
import com.food.order.sysyem.ports.output.repository.OrderRepository;
|
||||
import com.food.order.sysyem.valueobject.OrderStatus;
|
||||
import com.food.order.system.valueobject.OrderStatus;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -1,20 +1,21 @@
|
||||
package com.food.order.sysyem.mapper;
|
||||
package com.food.order.system.mapper;
|
||||
|
||||
import com.food.order.system.domain.entity.Order;
|
||||
import com.food.order.system.domain.entity.OrderItem;
|
||||
import com.food.order.system.domain.entity.Product;
|
||||
import com.food.order.system.domain.entity.Restaurant;
|
||||
import com.food.order.system.domain.event.OrderCancelledEvent;
|
||||
import com.food.order.system.domain.event.OrderCreatedEvent;
|
||||
import com.food.order.system.domain.event.OrderPaidEvent;
|
||||
import com.food.order.system.domain.valueobject.StreetAddress;
|
||||
import com.food.order.sysyem.dto.create.CreateOrderCommand;
|
||||
import com.food.order.sysyem.dto.create.CreateOrderResponse;
|
||||
import com.food.order.sysyem.dto.create.OrderAddress;
|
||||
import com.food.order.sysyem.dto.track.TrackOrderResponse;
|
||||
import com.food.order.sysyem.outbox.model.approval.OrderApprovalEventPayload;
|
||||
import com.food.order.sysyem.outbox.model.approval.OrderApprovalProduct;
|
||||
import com.food.order.sysyem.outbox.model.payment.OrderPaymentEventPayload;
|
||||
import com.food.order.sysyem.valueobject.*;
|
||||
import com.food.order.system.dto.create.CreateOrderCommand;
|
||||
import com.food.order.system.dto.create.CreateOrderResponse;
|
||||
import com.food.order.system.dto.create.OrderAddress;
|
||||
import com.food.order.system.dto.track.TrackOrderResponse;
|
||||
import com.food.order.system.outbox.model.approval.OrderApprovalEventPayload;
|
||||
import com.food.order.system.outbox.model.approval.OrderApprovalProduct;
|
||||
import com.food.order.system.outbox.model.payment.OrderPaymentEventPayload;
|
||||
import com.food.order.system.valueobject.*;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
@@ -23,6 +24,17 @@ import java.util.UUID;
|
||||
@Component
|
||||
public class OrderDataMapper {
|
||||
|
||||
public OrderPaymentEventPayload orderCancelledEventToOrderPaymentEventPayload(
|
||||
OrderCancelledEvent orderCancelledEvent) {
|
||||
return OrderPaymentEventPayload.builder()
|
||||
.orderId(orderCancelledEvent.getOrder().getId().getValue().toString())
|
||||
.paymentOrderStatus(PaymentOrderStatus.CANCELLED.name())
|
||||
.customerId(orderCancelledEvent.getOrder().getCustomerId().getValue().toString())
|
||||
.price(orderCancelledEvent.getOrder().getPrice().getAmount())
|
||||
.createdAt(orderCancelledEvent.getCreatedAt())
|
||||
.build();
|
||||
}
|
||||
|
||||
public OrderApprovalEventPayload orderPaidEventToOrderApprovalEventPayload(OrderPaidEvent orderPaidEvent) {
|
||||
return OrderApprovalEventPayload.builder()
|
||||
.orderId(orderPaidEvent.getOrder().getId().getValue().toString())
|
||||
@@ -80,7 +92,7 @@ public class OrderDataMapper {
|
||||
.build();
|
||||
}
|
||||
|
||||
private List<OrderItem> orderItemsToOrderItemEntities(List<com.food.order.sysyem.dto.create.OrderItem> orderItems) {
|
||||
private List<OrderItem> orderItemsToOrderItemEntities(List<com.food.order.system.dto.create.OrderItem> orderItems) {
|
||||
return orderItems.stream()
|
||||
.map(orderItem ->
|
||||
OrderItem.builder()
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.food.order.sysyem.outbox.model.approval;
|
||||
package com.food.order.system.outbox.model.approval;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.food.order.sysyem.outbox.model.approval;
|
||||
package com.food.order.system.outbox.model.approval;
|
||||
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.system.saga.SagaStatus;
|
||||
import com.food.order.sysyem.valueobject.OrderStatus;
|
||||
import com.food.order.system.valueobject.OrderStatus;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.food.order.sysyem.outbox.model.approval;
|
||||
package com.food.order.system.outbox.model.approval;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.food.order.sysyem.outbox.model.payment;
|
||||
package com.food.order.system.outbox.model.payment;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.food.order.sysyem.outbox.model.payment;
|
||||
package com.food.order.system.outbox.model.payment;
|
||||
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.system.saga.SagaStatus;
|
||||
import com.food.order.sysyem.valueobject.OrderStatus;
|
||||
import com.food.order.system.valueobject.OrderStatus;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
@@ -1,14 +1,14 @@
|
||||
package com.food.order.sysyem.outbox.scheduler.approval;
|
||||
package com.food.order.system.outbox.scheduler.approval;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.food.order.system.domain.exception.OrderDomainException;
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.system.outbox.model.approval.OrderApprovalEventPayload;
|
||||
import com.food.order.system.outbox.model.approval.OrderApprovalOutboxMessage;
|
||||
import com.food.order.system.saga.SagaStatus;
|
||||
import com.food.order.sysyem.outbox.model.approval.OrderApprovalEventPayload;
|
||||
import com.food.order.sysyem.outbox.model.approval.OrderApprovalOutboxMessage;
|
||||
import com.food.order.sysyem.ports.output.repository.ApprovalOutboxRepository;
|
||||
import com.food.order.sysyem.valueobject.OrderStatus;
|
||||
import com.food.order.system.ports.output.repository.ApprovalOutboxRepository;
|
||||
import com.food.order.system.valueobject.OrderStatus;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -73,9 +73,9 @@ public class ApprovalOutboxHelper {
|
||||
@Transactional
|
||||
public void saveApprovalOutboxMessage(OrderApprovalEventPayload payload,
|
||||
OrderStatus orderStatus,
|
||||
SagaStatus sagaStatus,
|
||||
OutboxStatus outboxStatus,
|
||||
UUID sagaId) {
|
||||
SagaStatus sagaStatus,
|
||||
OutboxStatus outboxStatus,
|
||||
UUID sagaId) {
|
||||
|
||||
save(OrderApprovalOutboxMessage.builder()
|
||||
.id(UUID.randomUUID())
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.food.order.sysyem.outbox.scheduler.approval;
|
||||
package com.food.order.system.outbox.scheduler.approval;
|
||||
|
||||
import com.food.order.system.domain.exception.OrderDomainException;
|
||||
import com.food.order.system.outbox.OutboxScheduler;
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.system.outbox.model.approval.OrderApprovalOutboxMessage;
|
||||
import com.food.order.system.saga.SagaStatus;
|
||||
import com.food.order.sysyem.outbox.model.approval.OrderApprovalOutboxMessage;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
@@ -16,7 +16,7 @@ import java.util.stream.Collectors;
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class RestaurantApprovalOutboxCleaner implements OutboxScheduler {
|
||||
public class RestaurantApprovalOutboxCleanerSchedule implements OutboxScheduler {
|
||||
|
||||
private final ApprovalOutboxHelper approvalOutboxHelper;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.food.order.sysyem.outbox.scheduler.approval;
|
||||
package com.food.order.system.outbox.scheduler.approval;
|
||||
|
||||
import com.food.order.system.domain.exception.OrderDomainException;
|
||||
import com.food.order.system.outbox.OutboxScheduler;
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.system.outbox.model.approval.OrderApprovalOutboxMessage;
|
||||
import com.food.order.system.saga.SagaStatus;
|
||||
import com.food.order.sysyem.outbox.model.approval.OrderApprovalOutboxMessage;
|
||||
import com.food.order.sysyem.ports.output.message.publisher.restaurantapproval.RestaurantApprovalRequestMessagePublisher;
|
||||
import com.food.order.system.ports.output.message.publisher.restaurantapproval.RestaurantApprovalRequestMessagePublisher;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
@@ -18,7 +18,7 @@ import java.util.stream.Collectors;
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class RestaurantApprovalOutboxMessage implements OutboxScheduler {
|
||||
public class RestaurantApprovalOutboxScheduler implements OutboxScheduler {
|
||||
|
||||
private final ApprovalOutboxHelper approvalOutboxHelper;
|
||||
private final RestaurantApprovalRequestMessagePublisher restaurantApprovalRequestMessagePublisher;
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.food.order.sysyem.outbox.scheduler.payment;
|
||||
package com.food.order.system.outbox.scheduler.payment;
|
||||
|
||||
import com.food.order.system.domain.exception.OrderDomainException;
|
||||
import com.food.order.system.outbox.OutboxScheduler;
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.system.outbox.model.payment.OrderPaymentOutboxMessage;
|
||||
import com.food.order.system.saga.SagaStatus;
|
||||
import com.food.order.sysyem.outbox.model.payment.OrderPaymentOutboxMessage;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
@@ -1,14 +1,14 @@
|
||||
package com.food.order.sysyem.outbox.scheduler.payment;
|
||||
package com.food.order.system.outbox.scheduler.payment;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.food.order.system.domain.exception.OrderDomainException;
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.system.outbox.model.payment.OrderPaymentEventPayload;
|
||||
import com.food.order.system.outbox.model.payment.OrderPaymentOutboxMessage;
|
||||
import com.food.order.system.ports.output.repository.PaymentOutboxRepository;
|
||||
import com.food.order.system.saga.SagaStatus;
|
||||
import com.food.order.sysyem.outbox.model.payment.OrderPaymentEventPayload;
|
||||
import com.food.order.sysyem.outbox.model.payment.OrderPaymentOutboxMessage;
|
||||
import com.food.order.sysyem.ports.output.repository.PaymentOutboxRepository;
|
||||
import com.food.order.sysyem.valueobject.OrderStatus;
|
||||
import com.food.order.system.valueobject.OrderStatus;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -1,12 +1,11 @@
|
||||
package com.food.order.sysyem.outbox.scheduler.payment;
|
||||
package com.food.order.system.outbox.scheduler.payment;
|
||||
|
||||
import com.food.order.system.domain.exception.OrderDomainException;
|
||||
import com.food.order.system.outbox.OutboxScheduler;
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.system.outbox.model.payment.OrderPaymentOutboxMessage;
|
||||
import com.food.order.system.ports.output.message.publisher.payment.PaymentRequestMessagePublisher;
|
||||
import com.food.order.system.saga.SagaStatus;
|
||||
import com.food.order.sysyem.outbox.model.payment.OrderPaymentOutboxMessage;
|
||||
import com.food.order.sysyem.ports.output.message.publisher.payment.PaymentRequestMessagePublisher;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -17,12 +16,17 @@ import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
//@RequiredArgsConstructor
|
||||
public class PaymentOutboxScheduler implements OutboxScheduler {
|
||||
|
||||
private final PaymentOutboxHelper paymentOutboxHelper;
|
||||
private final PaymentRequestMessagePublisher paymentRequestMessagePublisher;
|
||||
|
||||
public PaymentOutboxScheduler(PaymentOutboxHelper paymentOutboxHelper, PaymentRequestMessagePublisher paymentRequestMessagePublisher) {
|
||||
this.paymentOutboxHelper = paymentOutboxHelper;
|
||||
this.paymentRequestMessagePublisher = paymentRequestMessagePublisher;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Scheduled(fixedDelayString = "${order-service.outbox-scheduler-fixed-rate}",
|
||||
@@ -39,7 +43,7 @@ public class PaymentOutboxScheduler implements OutboxScheduler {
|
||||
.orElseThrow(
|
||||
() -> new OrderDomainException("No outbox message found for processing"));
|
||||
|
||||
if (Objects.nonNull(outboxMessageResponse) && outboxMessageResponse.size() > 0) {
|
||||
if (Objects.nonNull(outboxMessageResponse) && !outboxMessageResponse.isEmpty()) {
|
||||
|
||||
log.info("Received {} OrderPaymentOutboxMessage with ids : {} , sending message bus !" ,
|
||||
outboxMessageResponse.size(),
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.food.order.sysyem.ports.input.message.listener.payment;
|
||||
package com.food.order.system.ports.input.message.listener.payment;
|
||||
|
||||
import com.food.order.sysyem.dto.message.PaymentResponse;
|
||||
import com.food.order.system.dto.message.PaymentResponse;
|
||||
|
||||
public interface PaymentResponseMessageListener {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.food.order.sysyem.ports.input.message.listener.restaurantapproval;
|
||||
package com.food.order.system.ports.input.message.listener.restaurantapproval;
|
||||
|
||||
import com.food.order.sysyem.dto.message.RestaurantApprovalResponse;
|
||||
import com.food.order.system.dto.message.RestaurantApprovalResponse;
|
||||
|
||||
public interface RestaurantApprovalResponseMessageListener {
|
||||
void orderApproved(RestaurantApprovalResponse restaurantApprovalResponse);
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.food.order.system.ports.input.service;
|
||||
|
||||
import com.food.order.system.dto.create.CreateOrderCommand;
|
||||
import com.food.order.system.dto.create.CreateOrderResponse;
|
||||
import com.food.order.system.dto.track.TrackOrderQuery;
|
||||
import com.food.order.system.dto.track.TrackOrderResponse;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
public interface OrderApplicationService {
|
||||
|
||||
CreateOrderResponse createOrder(@Valid CreateOrderCommand createOrderCommand);
|
||||
TrackOrderResponse trackOrder(@Valid TrackOrderQuery trackOrderQuery);
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.food.order.sysyem.ports.output.message.publisher.payment;
|
||||
package com.food.order.system.ports.output.message.publisher.payment;
|
||||
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.sysyem.outbox.model.payment.OrderPaymentOutboxMessage;
|
||||
import com.food.order.system.outbox.model.payment.OrderPaymentOutboxMessage;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.food.order.sysyem.ports.output.message.publisher.restaurantapproval;
|
||||
package com.food.order.system.ports.output.message.publisher.restaurantapproval;
|
||||
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.sysyem.outbox.model.approval.OrderApprovalOutboxMessage;
|
||||
import com.food.order.system.outbox.model.approval.OrderApprovalOutboxMessage;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.food.order.sysyem.ports.output.repository;
|
||||
package com.food.order.system.ports.output.repository;
|
||||
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.system.outbox.model.approval.OrderApprovalOutboxMessage;
|
||||
import com.food.order.system.saga.SagaStatus;
|
||||
import com.food.order.sysyem.outbox.model.approval.OrderApprovalOutboxMessage;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.food.order.sysyem.ports.output.repository;
|
||||
package com.food.order.system.ports.output.repository;
|
||||
|
||||
import com.food.order.system.domain.entity.Customer;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.food.order.sysyem.ports.output.repository;
|
||||
package com.food.order.system.ports.output.repository;
|
||||
|
||||
import com.food.order.system.domain.entity.Order;
|
||||
import com.food.order.system.domain.valueobject.TrackingId;
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.food.order.sysyem.ports.output.repository;
|
||||
package com.food.order.system.ports.output.repository;
|
||||
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.system.outbox.model.payment.OrderPaymentOutboxMessage;
|
||||
import com.food.order.system.saga.SagaStatus;
|
||||
import com.food.order.sysyem.outbox.model.payment.OrderPaymentOutboxMessage;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.food.order.sysyem.ports.output.repository;
|
||||
package com.food.order.system.ports.output.repository;
|
||||
|
||||
import com.food.order.system.domain.entity.Restaurant;
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
package com.food.order.system.saga;
|
||||
|
||||
import com.food.order.system.domain.entity.Order;
|
||||
import com.food.order.system.domain.event.OrderCancelledEvent;
|
||||
import com.food.order.system.domain.exception.OrderDomainException;
|
||||
import com.food.order.system.domain.service.OrderDomainService;
|
||||
import com.food.order.system.helper.OrderSagaHelper;
|
||||
import com.food.order.system.mapper.OrderDataMapper;
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.system.outbox.model.approval.OrderApprovalOutboxMessage;
|
||||
import com.food.order.system.outbox.scheduler.approval.ApprovalOutboxHelper;
|
||||
import com.food.order.system.outbox.scheduler.payment.PaymentOutboxHelper;
|
||||
import com.food.order.system.dto.message.RestaurantApprovalResponse;
|
||||
import com.food.order.system.valueobject.OrderStatus;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.food.order.system.DomainConstants.UTC;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class OrderApprovalSaga implements SagaStep<RestaurantApprovalResponse> {
|
||||
|
||||
private final OrderDomainService orderDomainService;
|
||||
private final OrderSagaHelper orderSagaHelper;
|
||||
private final PaymentOutboxHelper paymentOutboxHelper;
|
||||
private final OrderDataMapper orderDataMapper;
|
||||
private final ApprovalOutboxHelper approvalOutboxHelper;
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void process(RestaurantApprovalResponse data) {
|
||||
|
||||
var messageResponse =
|
||||
approvalOutboxHelper.getApprovalOutboxMessageBySagaIdAndSagaStatus(
|
||||
UUID.fromString(data.getSagaId()),
|
||||
SagaStatus.PROCESSING)
|
||||
.orElseThrow(() -> {
|
||||
log.error("Approval outbox message not found for saga id: {}", data.getSagaId());
|
||||
return new OrderDomainException("Approval outbox message not found for saga id: " + data.getSagaId());
|
||||
});
|
||||
|
||||
var order = approveOrder(data);
|
||||
|
||||
var sagaStatus = orderSagaHelper.orderStatusToSagaStatus(order.getStatus());
|
||||
|
||||
approvalOutboxHelper.save(getUpdatedApprovalOutboxMessage(messageResponse,order.getStatus(), sagaStatus));
|
||||
|
||||
approvalOutboxHelper.save(getUpdatedPaymentOutboxMessage(messageResponse.getSagaId(),
|
||||
order.getStatus(), sagaStatus));
|
||||
|
||||
|
||||
|
||||
log.info("Order approved: {}", order);
|
||||
}
|
||||
|
||||
private OrderApprovalOutboxMessage getUpdatedPaymentOutboxMessage(UUID sagaId,
|
||||
OrderStatus status,
|
||||
SagaStatus sagaStatus) {
|
||||
var message = approvalOutboxHelper.getApprovalOutboxMessageBySagaIdAndSagaStatus(
|
||||
sagaId,
|
||||
SagaStatus.PROCESSING)
|
||||
.orElseThrow(() -> {
|
||||
log.error("Approval outbox message not found for saga id: {}", sagaId);
|
||||
return new OrderDomainException("Approval outbox message not found for saga id: " + sagaId);
|
||||
});
|
||||
|
||||
message.setProcessedAt(ZonedDateTime.now(ZoneId.of(UTC)));
|
||||
message.setSagaStatus(sagaStatus);
|
||||
message.setOrderStatus(status);
|
||||
return message;
|
||||
}
|
||||
|
||||
private OrderApprovalOutboxMessage getUpdatedApprovalOutboxMessage(OrderApprovalOutboxMessage messageResponse,
|
||||
OrderStatus status,
|
||||
SagaStatus sagaStatus) {
|
||||
messageResponse.setProcessedAt(ZonedDateTime.now(ZoneId.of(UTC)));
|
||||
messageResponse.setSagaStatus(sagaStatus);
|
||||
messageResponse.setOrderStatus(status);
|
||||
return messageResponse;
|
||||
}
|
||||
|
||||
|
||||
private Order approveOrder(RestaurantApprovalResponse data) {
|
||||
var order = orderSagaHelper.findOrder(data.getOrderId());
|
||||
orderDomainService.approve(order);
|
||||
orderSagaHelper.saveOrder(order);
|
||||
return order;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void rollback(RestaurantApprovalResponse data) {
|
||||
|
||||
var message = approvalOutboxHelper.getApprovalOutboxMessageBySagaIdAndSagaStatus(
|
||||
UUID.fromString(data.getSagaId()),
|
||||
SagaStatus.PROCESSING)
|
||||
.orElseThrow(
|
||||
() -> {
|
||||
log.error("Approval outbox message not found for saga id: {}", data.getSagaId());
|
||||
return new OrderDomainException("Approval outbox message not found for saga id: " +
|
||||
data.getSagaId());
|
||||
}
|
||||
);
|
||||
|
||||
var event = rollbackOrder(data);
|
||||
|
||||
var sagaStatus = orderSagaHelper.orderStatusToSagaStatus(event.getOrder().getStatus());
|
||||
|
||||
approvalOutboxHelper.save(getUpdatedApprovalOutboxMessage(message, event.getOrder().getStatus(), sagaStatus));
|
||||
|
||||
paymentOutboxHelper.savePaymentOutboxMessage(
|
||||
orderDataMapper.orderCancelledEventToOrderPaymentEventPayload(event),
|
||||
event.getOrder().getStatus(),
|
||||
sagaStatus,
|
||||
OutboxStatus.STARTED,
|
||||
message.getSagaId()
|
||||
);
|
||||
|
||||
log.info("Order cancelled event id: {}", event.getOrder().getId());
|
||||
}
|
||||
|
||||
private OrderCancelledEvent rollbackOrder(RestaurantApprovalResponse data) {
|
||||
var order = orderSagaHelper.findOrder(data.getOrderId());
|
||||
var event = orderDomainService.cancelOrderPayment(
|
||||
order,
|
||||
data.getFailureMessages());
|
||||
orderSagaHelper.saveOrder(order);
|
||||
return event;
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,19 @@
|
||||
package com.food.order.sysyem.saga;
|
||||
package com.food.order.system.saga;
|
||||
|
||||
import com.food.order.system.domain.entity.Order;
|
||||
import com.food.order.system.domain.event.OrderPaidEvent;
|
||||
import com.food.order.system.domain.exception.OrderDomainException;
|
||||
import com.food.order.system.domain.service.OrderDomainService;
|
||||
import com.food.order.system.dto.message.PaymentResponse;
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.system.saga.SagaStatus;
|
||||
import com.food.order.system.saga.SagaStep;
|
||||
import com.food.order.sysyem.dto.message.PaymentResponse;
|
||||
import com.food.order.sysyem.helper.OrderSagaHelper;
|
||||
import com.food.order.sysyem.mapper.OrderDataMapper;
|
||||
import com.food.order.sysyem.outbox.model.approval.OrderApprovalOutboxMessage;
|
||||
import com.food.order.sysyem.outbox.model.payment.OrderPaymentOutboxMessage;
|
||||
import com.food.order.sysyem.outbox.scheduler.approval.ApprovalOutboxHelper;
|
||||
import com.food.order.sysyem.outbox.scheduler.payment.PaymentOutboxHelper;
|
||||
import com.food.order.sysyem.valueobject.OrderStatus;
|
||||
import com.food.order.sysyem.valueobject.PaymentStatus;
|
||||
import com.food.order.system.outbox.model.approval.OrderApprovalOutboxMessage;
|
||||
import com.food.order.system.outbox.model.payment.OrderPaymentOutboxMessage;
|
||||
import com.food.order.system.helper.OrderSagaHelper;
|
||||
import com.food.order.system.mapper.OrderDataMapper;
|
||||
import com.food.order.system.outbox.scheduler.approval.ApprovalOutboxHelper;
|
||||
import com.food.order.system.outbox.scheduler.payment.PaymentOutboxHelper;
|
||||
import com.food.order.system.valueobject.OrderStatus;
|
||||
import com.food.order.system.valueobject.PaymentStatus;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -25,7 +23,7 @@ import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.food.order.sysyem.DomainConstants.UTC;
|
||||
import static com.food.order.system.DomainConstants.UTC;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.food.order.sysyem.ports.input.service;
|
||||
|
||||
import com.food.order.sysyem.dto.create.CreateOrderCommand;
|
||||
import com.food.order.sysyem.dto.create.CreateOrderResponse;
|
||||
import com.food.order.sysyem.dto.track.TrackOrderQuery;
|
||||
import com.food.order.sysyem.dto.track.TrackOrderResponse;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
public interface OrderApplicationService {
|
||||
|
||||
CreateOrderResponse createOrder(@Valid CreateOrderCommand createOrderCommand);
|
||||
TrackOrderResponse trackOrder(@Valid TrackOrderQuery trackOrderQuery);
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package com.food.order.sysyem.saga;
|
||||
|
||||
import com.food.order.system.domain.service.OrderDomainService;
|
||||
import com.food.order.system.saga.SagaStep;
|
||||
import com.food.order.sysyem.dto.message.RestaurantApprovalResponse;
|
||||
import com.food.order.sysyem.helper.OrderSagaHelper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class OrderApprovalSaga implements SagaStep<RestaurantApprovalResponse> {
|
||||
|
||||
private final OrderDomainService orderDomainService;
|
||||
private final OrderSagaHelper orderSagaHelper;
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void process(RestaurantApprovalResponse data) {
|
||||
log.info("Approving order with id: {}", data.getOrderId());
|
||||
var order = orderSagaHelper.findOrder(data.getOrderId());
|
||||
orderDomainService.approve(order);
|
||||
orderSagaHelper.saveOrder(order);
|
||||
log.info("Order approved: {}", order);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void rollback(RestaurantApprovalResponse data) {
|
||||
log.info("Approving order with id: {}", data.getOrderId());
|
||||
var order = orderSagaHelper.findOrder(data.getOrderId());
|
||||
var cancelEvent = orderDomainService.cancelOrderPayment
|
||||
(order,
|
||||
data.getFailureMessages());
|
||||
orderSagaHelper.saveOrder(order);
|
||||
log.info("Order cancelled: {}", order);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
package com.food.order.system;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.food.order.system.domain.entity.Customer;
|
||||
import com.food.order.system.domain.entity.Order;
|
||||
import com.food.order.system.domain.entity.Product;
|
||||
import com.food.order.system.domain.entity.Restaurant;
|
||||
import com.food.order.system.domain.exception.OrderDomainException;
|
||||
import com.food.order.system.dto.create.CreateOrderCommand;
|
||||
import com.food.order.system.dto.create.CreateOrderResponse;
|
||||
import com.food.order.system.dto.create.OrderAddress;
|
||||
import com.food.order.system.dto.create.OrderItem;
|
||||
import com.food.order.system.mapper.OrderDataMapper;
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.system.outbox.model.payment.OrderPaymentEventPayload;
|
||||
import com.food.order.system.outbox.model.payment.OrderPaymentOutboxMessage;
|
||||
import com.food.order.system.ports.input.service.OrderApplicationService;
|
||||
import com.food.order.system.ports.output.repository.CustomerRepository;
|
||||
import com.food.order.system.ports.output.repository.OrderRepository;
|
||||
import com.food.order.system.ports.output.repository.PaymentOutboxRepository;
|
||||
import com.food.order.system.ports.output.repository.RestaurantRepository;
|
||||
import com.food.order.system.saga.SagaStatus;
|
||||
import com.food.order.system.valueobject.*;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.food.order.system.outbox.order.SagaConst.ORDER_PROCESSING_SAGA;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
@SpringBootTest(classes = OrderTestConfiguration.class)
|
||||
class OrderApplicationServiceTest {
|
||||
|
||||
@Autowired
|
||||
private OrderApplicationService orderApplicationService;
|
||||
|
||||
@Autowired
|
||||
private OrderDataMapper orderDataMapper;
|
||||
|
||||
@Autowired
|
||||
private OrderRepository orderRepository;
|
||||
|
||||
@Autowired
|
||||
private CustomerRepository customerRepository;
|
||||
|
||||
@Autowired
|
||||
private RestaurantRepository restaurantRepository;
|
||||
|
||||
@Autowired
|
||||
private PaymentOutboxRepository paymentOutboxRepository;
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
private CreateOrderCommand createOrderCommand;
|
||||
private CreateOrderCommand createOrderCommandWrongPrice;
|
||||
private CreateOrderCommand createOrderCommandWrongProductPrice;
|
||||
private final UUID CUSTOMER_ID = UUID.fromString("d215b5f8-0249-4dc5-89a3-51fd148cfb41");
|
||||
private final UUID RESTAURANT_ID = UUID.fromString("d215b5f8-0249-4dc5-89a3-51fd148cfb45");
|
||||
private final UUID PRODUCT_ID = UUID.fromString("d215b5f8-0249-4dc5-89a3-51fd148cfb48");
|
||||
private final UUID ORDER_ID = UUID.fromString("15a497c1-0f4b-4eff-b9f4-c402c8c07afb");
|
||||
private final UUID SAGA_ID = UUID.fromString("15a497c1-0f4b-4eff-b9f4-c402c8c07afa");
|
||||
private final BigDecimal PRICE = new BigDecimal("200.00");
|
||||
|
||||
@BeforeAll
|
||||
public void init() {
|
||||
createOrderCommand = CreateOrderCommand.builder()
|
||||
.customerId(CUSTOMER_ID)
|
||||
.restaurantId(RESTAURANT_ID)
|
||||
.orderAddress(OrderAddress.builder()
|
||||
.street("street_1")
|
||||
.postalCode("1000AB")
|
||||
.city("Paris")
|
||||
.build())
|
||||
.price(PRICE)
|
||||
.orderItems(List.of(OrderItem.builder()
|
||||
.productId(PRODUCT_ID)
|
||||
.quantity(1)
|
||||
.price(new BigDecimal("50.00"))
|
||||
.subTotal(new BigDecimal("50.00"))
|
||||
.build(),
|
||||
OrderItem.builder()
|
||||
.productId(PRODUCT_ID)
|
||||
.quantity(3)
|
||||
.price(new BigDecimal("50.00"))
|
||||
.subTotal(new BigDecimal("150.00"))
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
createOrderCommandWrongPrice = CreateOrderCommand.builder()
|
||||
.customerId(CUSTOMER_ID)
|
||||
.restaurantId(RESTAURANT_ID)
|
||||
.orderAddress(OrderAddress.builder()
|
||||
.street("street_1")
|
||||
.postalCode("1000AB")
|
||||
.city("Paris")
|
||||
.build())
|
||||
.price(new BigDecimal("250.00"))
|
||||
.orderItems(List.of(OrderItem.builder()
|
||||
.productId(PRODUCT_ID)
|
||||
.quantity(1)
|
||||
.price(new BigDecimal("50.00"))
|
||||
.subTotal(new BigDecimal("50.00"))
|
||||
.build(),
|
||||
OrderItem.builder()
|
||||
.productId(PRODUCT_ID)
|
||||
.quantity(3)
|
||||
.price(new BigDecimal("50.00"))
|
||||
.subTotal(new BigDecimal("150.00"))
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
createOrderCommandWrongProductPrice = CreateOrderCommand.builder()
|
||||
.customerId(CUSTOMER_ID)
|
||||
.restaurantId(RESTAURANT_ID)
|
||||
.orderAddress(OrderAddress.builder()
|
||||
.street("street_1")
|
||||
.postalCode("1000AB")
|
||||
.city("Paris")
|
||||
.build())
|
||||
.price(new BigDecimal("210.00"))
|
||||
.orderItems(List.of(OrderItem.builder()
|
||||
.productId(PRODUCT_ID)
|
||||
.quantity(1)
|
||||
.price(new BigDecimal("60.00"))
|
||||
.subTotal(new BigDecimal("60.00"))
|
||||
.build(),
|
||||
OrderItem.builder()
|
||||
.productId(PRODUCT_ID)
|
||||
.quantity(3)
|
||||
.price(new BigDecimal("50.00"))
|
||||
.subTotal(new BigDecimal("150.00"))
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
Customer customer = new Customer(new CustomerId(CUSTOMER_ID));
|
||||
|
||||
Restaurant restaurantResponse = Restaurant.builder()
|
||||
.id(new RestaurantId(createOrderCommand.restaurantId()))
|
||||
.products(List.of(new Product(new ProductId(PRODUCT_ID), "product-1", new Money(new BigDecimal("50.00"))),
|
||||
new Product(new ProductId(PRODUCT_ID), "product-2", new Money(new BigDecimal("50.00")))))
|
||||
.isActive(true)
|
||||
.build();
|
||||
|
||||
Order order = orderDataMapper.createOrderCommandToOrder(createOrderCommand);
|
||||
order.setId(new OrderId(ORDER_ID));
|
||||
|
||||
when(customerRepository.findCustomer(CUSTOMER_ID)).thenReturn(Optional.of(customer));
|
||||
when(restaurantRepository.findRestaurantInformation(orderDataMapper.createOrderCommandToRestaurant(createOrderCommand)))
|
||||
.thenReturn(Optional.of(restaurantResponse));
|
||||
when(orderRepository.save(any(Order.class))).thenReturn(order);
|
||||
when(paymentOutboxRepository.save(any(OrderPaymentOutboxMessage.class))).thenReturn(getOrderPaymentOutboxMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateOrder() {
|
||||
CreateOrderResponse createOrderResponse = orderApplicationService.createOrder(createOrderCommand);
|
||||
assertEquals(OrderStatus.PENDING, createOrderResponse.orderStatus());
|
||||
assertEquals("Order created successfully", createOrderResponse.message());
|
||||
assertNotNull(createOrderResponse.orderTrackingId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateOrderWithWrongTotalPrice() {
|
||||
OrderDomainException orderDomainException = assertThrows(OrderDomainException.class,
|
||||
() -> orderApplicationService.createOrder(createOrderCommandWrongPrice));
|
||||
assertEquals("Total price: 250.00 is not equal to Order items total: 200.00!",
|
||||
orderDomainException.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateOrderWithWrongProductPrice() {
|
||||
OrderDomainException orderDomainException = assertThrows(OrderDomainException.class,
|
||||
() -> orderApplicationService.createOrder(createOrderCommandWrongProductPrice));
|
||||
assertEquals(orderDomainException.getMessage(),
|
||||
"Order item price: 60.00 is not valid for product " + PRODUCT_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateOrderWithPassiveRestaurant() {
|
||||
Restaurant restaurantResponse = Restaurant.builder()
|
||||
.id(new RestaurantId(createOrderCommand.restaurantId()))
|
||||
.products(List.of(new Product(new ProductId(PRODUCT_ID), "product-1", new Money(new BigDecimal("50.00"))),
|
||||
new Product(new ProductId(PRODUCT_ID), "product-2", new Money(new BigDecimal("50.00")))))
|
||||
.isActive(false)
|
||||
.build();
|
||||
when(restaurantRepository.findRestaurantInformation(orderDataMapper.createOrderCommandToRestaurant(createOrderCommand)))
|
||||
.thenReturn(Optional.of(restaurantResponse));
|
||||
OrderDomainException orderDomainException = assertThrows(OrderDomainException.class,
|
||||
() -> orderApplicationService.createOrder(createOrderCommand));
|
||||
assertEquals(orderDomainException.getMessage(),
|
||||
"Restaurant with id " + RESTAURANT_ID + " is currently not active!");
|
||||
}
|
||||
|
||||
private OrderPaymentOutboxMessage getOrderPaymentOutboxMessage() {
|
||||
OrderPaymentEventPayload orderPaymentEventPayload = OrderPaymentEventPayload.builder()
|
||||
.orderId(ORDER_ID.toString())
|
||||
.customerId(CUSTOMER_ID.toString())
|
||||
.price(PRICE)
|
||||
.createdAt(ZonedDateTime.now())
|
||||
.paymentOrderStatus(PaymentOrderStatus.PENDING.name())
|
||||
.build();
|
||||
|
||||
return OrderPaymentOutboxMessage.builder()
|
||||
.id(UUID.randomUUID())
|
||||
.sagaId(SAGA_ID)
|
||||
.createdAt(ZonedDateTime.now())
|
||||
.type(ORDER_PROCESSING_SAGA)
|
||||
.payload(createPayload(orderPaymentEventPayload))
|
||||
.orderStatus(OrderStatus.PENDING)
|
||||
.sagaStatus(SagaStatus.STARTED)
|
||||
.outboxStatus(OutboxStatus.STARTED)
|
||||
.version(0)
|
||||
.build();
|
||||
}
|
||||
|
||||
private String createPayload(OrderPaymentEventPayload orderPaymentEventPayload) {
|
||||
try {
|
||||
return objectMapper.writeValueAsString(orderPaymentEventPayload);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new OrderDomainException("Cannot create OrderPaymentEventPayload object!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.food.order.system;
|
||||
|
||||
import com.food.order.system.domain.service.OrderDomainService;
|
||||
import com.food.order.system.domain.service.impl.OrderDomainServiceImpl;
|
||||
import com.food.order.system.ports.output.message.publisher.payment.PaymentRequestMessagePublisher;
|
||||
import com.food.order.system.ports.output.message.publisher.restaurantapproval.RestaurantApprovalRequestMessagePublisher;
|
||||
import com.food.order.system.ports.output.repository.*;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
@SpringBootApplication(scanBasePackages = "com.food.order")
|
||||
public class OrderTestConfiguration {
|
||||
|
||||
@Bean
|
||||
public PaymentRequestMessagePublisher paymentRequestMessagePublisher() {
|
||||
return Mockito.mock(PaymentRequestMessagePublisher.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RestaurantApprovalRequestMessagePublisher restaurantApprovalRequestMessagePublisher() {
|
||||
return Mockito.mock(RestaurantApprovalRequestMessagePublisher.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OrderRepository orderRepository() {
|
||||
return Mockito.mock(OrderRepository.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CustomerRepository customerRepository() {
|
||||
return Mockito.mock(CustomerRepository.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RestaurantRepository restaurantRepository() {
|
||||
return Mockito.mock(RestaurantRepository.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PaymentOutboxRepository paymentOutboxRepository() {
|
||||
return Mockito.mock(PaymentOutboxRepository.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ApprovalOutboxRepository approvalOutboxRepository() {
|
||||
return Mockito.mock(ApprovalOutboxRepository.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OrderDomainService orderDomainService() {
|
||||
return new OrderDomainServiceImpl();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
order-service:
|
||||
outbox-scheduler-fixed-rate: 10000
|
||||
outbox-scheduler-initial-delay: 10000
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.food.order.system.domain.entity;
|
||||
|
||||
import com.food.order.sysyem.entity.AggregateRoot;
|
||||
import com.food.order.sysyem.valueobject.CustomerId;
|
||||
import com.food.order.system.entity.AggregateRoot;
|
||||
import com.food.order.system.valueobject.CustomerId;
|
||||
|
||||
public class Customer extends AggregateRoot<CustomerId> {
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.food.order.system.domain.entity;
|
||||
|
||||
import com.food.order.sysyem.entity.AggregateRoot;
|
||||
import com.food.order.system.entity.AggregateRoot;
|
||||
import com.food.order.system.domain.exception.OrderDomainException;
|
||||
import com.food.order.system.domain.valueobject.OrderItemId;
|
||||
import com.food.order.system.domain.valueobject.StreetAddress;
|
||||
import com.food.order.system.domain.valueobject.TrackingId;
|
||||
import com.food.order.sysyem.valueobject.*;
|
||||
import com.food.order.system.valueobject.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.food.order.system.domain.entity;
|
||||
|
||||
import com.food.order.sysyem.entity.BaseEntity;
|
||||
import com.food.order.sysyem.valueobject.Money;
|
||||
import com.food.order.sysyem.valueobject.OrderId;
|
||||
import com.food.order.system.entity.BaseEntity;
|
||||
import com.food.order.system.valueobject.Money;
|
||||
import com.food.order.system.valueobject.OrderId;
|
||||
import com.food.order.system.domain.valueobject.OrderItemId;
|
||||
|
||||
public class OrderItem extends BaseEntity<OrderItemId> {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.food.order.system.domain.entity;
|
||||
|
||||
import com.food.order.sysyem.entity.BaseEntity;
|
||||
import com.food.order.sysyem.valueobject.Money;
|
||||
import com.food.order.sysyem.valueobject.ProductId;
|
||||
import com.food.order.system.entity.BaseEntity;
|
||||
import com.food.order.system.valueobject.Money;
|
||||
import com.food.order.system.valueobject.ProductId;
|
||||
|
||||
public class Product extends BaseEntity<ProductId> {
|
||||
private String name;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.food.order.system.domain.entity;
|
||||
|
||||
import com.food.order.sysyem.entity.AggregateRoot;
|
||||
import com.food.order.sysyem.valueobject.RestaurantId;
|
||||
import com.food.order.system.entity.AggregateRoot;
|
||||
import com.food.order.system.valueobject.RestaurantId;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.food.order.system.domain.event;
|
||||
|
||||
import com.food.order.system.domain.entity.Order;
|
||||
import com.food.order.sysyem.event.publisher.DomainEventPublisher;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.food.order.system.domain.event;
|
||||
|
||||
import com.food.order.sysyem.event.DomainEvent;
|
||||
import com.food.order.system.event.DomainEvent;
|
||||
import com.food.order.system.domain.entity.Order;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.food.order.system.domain.event;
|
||||
|
||||
import com.food.order.system.domain.entity.Order;
|
||||
import com.food.order.sysyem.event.publisher.DomainEventPublisher;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.food.order.system.domain.exception;
|
||||
|
||||
import com.food.order.sysyem.exception.DomainException;
|
||||
import com.food.order.system.exception.DomainException;
|
||||
|
||||
public class OrderDomainException extends DomainException {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.food.order.system.domain.exception;
|
||||
|
||||
import com.food.order.sysyem.exception.DomainException;
|
||||
import com.food.order.system.exception.DomainException;
|
||||
|
||||
public class OrderNotFoundException extends DomainException {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.food.order.system.domain.valueobject;
|
||||
|
||||
import com.food.order.sysyem.valueobject.BaseId;
|
||||
import com.food.order.system.valueobject.BaseId;
|
||||
|
||||
public class OrderItemId extends BaseId<Long> {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.food.order.system.domain.valueobject;
|
||||
|
||||
import com.food.order.sysyem.valueobject.BaseId;
|
||||
import com.food.order.system.valueobject.BaseId;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user