Outbox Message and Scheduler class implemented part - 4.
This commit is contained in:
@@ -34,6 +34,25 @@
|
||||
<artifactId>payment-domain-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-json</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>outbox</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.food.order</groupId>
|
||||
<artifactId>saga</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package com.food.order.system.payment.application.service;
|
||||
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.system.payment.application.service.dto.PaymentRequest;
|
||||
import com.food.order.system.payment.application.service.exception.PaymentApplicationServiceException;
|
||||
import com.food.order.system.payment.application.service.mapper.PaymentDataMapper;
|
||||
import com.food.order.system.payment.application.service.outbox.scheduler.OrderOutboxHelper;
|
||||
import com.food.order.system.payment.application.service.ports.output.message.publisher.PaymentResponseMessagePublisher;
|
||||
import com.food.order.system.payment.application.service.ports.output.repository.CreditEntryRepository;
|
||||
import com.food.order.system.payment.application.service.ports.output.repository.CreditHistoryRepository;
|
||||
import com.food.order.system.payment.application.service.ports.output.repository.PaymentRepository;
|
||||
@@ -10,12 +13,8 @@ import com.food.order.system.payment.service.domain.PaymentDomainService;
|
||||
import com.food.order.system.payment.service.domain.entity.CreditEntry;
|
||||
import com.food.order.system.payment.service.domain.entity.CreditHistory;
|
||||
import com.food.order.system.payment.service.domain.entity.Payment;
|
||||
import com.food.order.system.payment.service.domain.event.PaymentCancelledEvent;
|
||||
import com.food.order.system.payment.service.domain.event.PaymentCompletedEvent;
|
||||
import com.food.order.system.payment.service.domain.event.PaymentEvent;
|
||||
import com.food.order.system.payment.service.domain.event.PaymentFailedEvent;
|
||||
import com.food.order.system.event.publisher.DomainEventPublisher;
|
||||
import com.food.order.system.valueobject.CustomerId;
|
||||
import com.food.order.system.valueobject.PaymentStatus;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -30,18 +29,24 @@ import java.util.UUID;
|
||||
@RequiredArgsConstructor
|
||||
public class PaymentRequestHelper {
|
||||
private final PaymentDomainService paymentDomainService;
|
||||
|
||||
private final OrderOutboxHelper orderOutboxHelper;
|
||||
|
||||
private final PaymentResponseMessagePublisher paymentResponseMessagePublisher;
|
||||
private final PaymentDataMapper paymentDataMapper;
|
||||
private final PaymentRepository paymentRepository;
|
||||
private final CreditEntryRepository creditEntryRepository;
|
||||
private final CreditHistoryRepository creditHistoryRepository;
|
||||
|
||||
private final DomainEventPublisher<PaymentCompletedEvent> publisher;
|
||||
private final DomainEventPublisher<PaymentCancelledEvent> publisherCancelled;
|
||||
|
||||
private final DomainEventPublisher<PaymentFailedEvent> failedEventDomainEventPublisher;
|
||||
|
||||
@Transactional
|
||||
public PaymentEvent persistPayment(PaymentRequest paymentRequest) {
|
||||
public void persistPayment(PaymentRequest paymentRequest) {
|
||||
|
||||
if (publishIfOutboxMessageProcessedForPayment(paymentRequest,PaymentStatus.COMPLETED)) {
|
||||
log.info("Outbox Message with sagaId : {} already save !", paymentRequest.getSagaId());
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("Received payment complete event for id : {}", paymentRequest.getOrderId());
|
||||
var payment = paymentDataMapper.paymentRequestModelToPayment(paymentRequest);
|
||||
var creditEntry = getCreditEntry(payment.getCustomerId());
|
||||
@@ -49,14 +54,40 @@ public class PaymentRequestHelper {
|
||||
List<String> failureMessage = new ArrayList<>();
|
||||
|
||||
var paymentEvent = paymentDomainService.validateAndInitializePayment
|
||||
(payment, creditEntry, creditHistory, failureMessage,publisher,failedEventDomainEventPublisher);
|
||||
(payment, creditEntry, creditHistory, failureMessage);
|
||||
|
||||
persistDbObject(payment, creditEntry, creditHistory, failureMessage);
|
||||
return paymentEvent;
|
||||
|
||||
orderOutboxHelper.saveOrderOutboxMessage(paymentDataMapper.paymentEventToOrderEventPayload(paymentEvent),
|
||||
paymentEvent.getPayment().getStatus(),
|
||||
OutboxStatus.STARTED,
|
||||
UUID.fromString(paymentRequest.getSagaId()));
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private boolean publishIfOutboxMessageProcessedForPayment(PaymentRequest paymentRequest,
|
||||
PaymentStatus paymentStatus) {
|
||||
var outboxMessage = orderOutboxHelper.getCompletedOrderOutboxMessageBySagaIdAndPaymentStatus(
|
||||
UUID.fromString(paymentRequest.getSagaId()), paymentStatus);
|
||||
if (outboxMessage.isPresent()) {
|
||||
paymentResponseMessagePublisher.publish(outboxMessage.get(),
|
||||
orderOutboxHelper::updateOutboxMessage);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public PaymentEvent persistCancelPayment(PaymentRequest paymentRequest) {
|
||||
public void persistCancelPayment(PaymentRequest paymentRequest) {
|
||||
|
||||
if (publishIfOutboxMessageProcessedForPayment(paymentRequest,PaymentStatus.CANCELED)) {
|
||||
log.info("Outbox Message with sagaId : {} already save !", paymentRequest.getSagaId());
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("Received payment cancel event for id : {}", paymentRequest.getOrderId());
|
||||
var payment = paymentRepository.findByOrderId
|
||||
(UUID.fromString(paymentRequest.getOrderId())).orElseThrow(
|
||||
@@ -65,13 +96,22 @@ public class PaymentRequestHelper {
|
||||
var creditHistory = getCreditHistory(payment.getCustomerId());
|
||||
List<String> failureMessage = new ArrayList<>();
|
||||
var paymentEvent = paymentDomainService.validateAndCancelledPayment
|
||||
(payment, creditEntry, creditHistory, failureMessage,publisherCancelled,failedEventDomainEventPublisher);
|
||||
(payment, creditEntry, creditHistory, failureMessage);
|
||||
|
||||
persistDbObject(payment, creditEntry, creditHistory, failureMessage);
|
||||
return paymentEvent;
|
||||
|
||||
|
||||
orderOutboxHelper.saveOrderOutboxMessage(paymentDataMapper.paymentEventToOrderEventPayload(paymentEvent),
|
||||
paymentEvent.getPayment().getStatus(),
|
||||
OutboxStatus.STARTED,
|
||||
UUID.fromString(paymentRequest.getSagaId()));
|
||||
|
||||
}
|
||||
|
||||
private void persistDbObject(Payment payment, CreditEntry creditEntry, List<CreditHistory> creditHistory, List<String> failureMessage) {
|
||||
private void persistDbObject(Payment payment,
|
||||
CreditEntry creditEntry,
|
||||
List<CreditHistory> creditHistory,
|
||||
List<String> failureMessage) {
|
||||
paymentRepository.save(payment);
|
||||
if (failureMessage.isEmpty()) {
|
||||
creditEntryRepository.save(creditEntry);
|
||||
@@ -80,11 +120,13 @@ public class PaymentRequestHelper {
|
||||
}
|
||||
private List<CreditHistory> getCreditHistory(CustomerId customerId) {
|
||||
return creditHistoryRepository.findByCustomerId(customerId).orElseThrow(
|
||||
() -> new PaymentApplicationServiceException("No credit history found for customer id : " + customerId));
|
||||
() -> new PaymentApplicationServiceException
|
||||
("No credit history found for customer id : " + customerId));
|
||||
}
|
||||
|
||||
private CreditEntry getCreditEntry(CustomerId customerId) {
|
||||
return creditEntryRepository.findByCustomerId(customerId).orElseThrow(
|
||||
() -> new PaymentApplicationServiceException("Credit entry not found for customer id : " + customerId));
|
||||
() -> new PaymentApplicationServiceException
|
||||
("Credit entry not found for customer id : " + customerId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.food.order.system.payment.application.service;
|
||||
|
||||
import com.food.order.system.payment.application.service.dto.PaymentRequest;
|
||||
import com.food.order.system.payment.application.service.ports.input.message.listener.PaymentRequestMessageListener;
|
||||
import com.food.order.system.payment.service.domain.event.PaymentEvent;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -16,20 +15,13 @@ public class PaymentRequestMessageListenerImpl implements PaymentRequestMessageL
|
||||
|
||||
@Override
|
||||
public void completePayment(PaymentRequest paymentRequest) {
|
||||
var event = paymentRequestHelper.persistPayment(paymentRequest);
|
||||
fireEvent(event);
|
||||
paymentRequestHelper.persistPayment(paymentRequest);
|
||||
}
|
||||
@Override
|
||||
public void cancelPayment(PaymentRequest paymentRequest) {
|
||||
var event = paymentRequestHelper.persistCancelPayment(paymentRequest);
|
||||
fireEvent(event);
|
||||
paymentRequestHelper.persistCancelPayment(paymentRequest);
|
||||
}
|
||||
private void fireEvent(PaymentEvent event) {
|
||||
|
||||
log.info("Firing event : {}", event);
|
||||
event.fire();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.food.order.system.payment.application.service.exception;
|
||||
|
||||
import com.food.order.system.exception.DomainException;
|
||||
|
||||
public class PaymentDomainException extends DomainException {
|
||||
|
||||
public PaymentDomainException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public PaymentDomainException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.food.order.system.payment.application.service.mapper;
|
||||
|
||||
import com.food.order.system.payment.application.service.dto.PaymentRequest;
|
||||
import com.food.order.system.payment.application.service.outbox.model.OrderEventPayload;
|
||||
import com.food.order.system.payment.service.domain.entity.Payment;
|
||||
import com.food.order.system.payment.service.domain.event.PaymentEvent;
|
||||
import com.food.order.system.valueobject.CustomerId;
|
||||
import com.food.order.system.valueobject.Money;
|
||||
import com.food.order.system.valueobject.OrderId;
|
||||
@@ -20,4 +22,17 @@ public class PaymentDataMapper {
|
||||
.price(new Money(paymentRequest.getPrice()))
|
||||
.build();
|
||||
}
|
||||
|
||||
public OrderEventPayload paymentEventToOrderEventPayload(PaymentEvent payment) {
|
||||
return OrderEventPayload.builder()
|
||||
.orderId(payment.getPayment().getOrderId().getValue().toString())
|
||||
.customerId(payment.getPayment().getCustomerId().getValue().toString())
|
||||
.price(payment.getPayment().getPrice().getAmount())
|
||||
.paymentId(payment.getPayment().getId().toString())
|
||||
.createdAt(payment.getCreatedAt())
|
||||
.failureMessages(payment.getFailureMessages())
|
||||
.paymentStatus(payment.getPayment().getStatus().toString())
|
||||
.build();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.food.order.system.payment.application.service.outbox.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
public class OrderEventPayload {
|
||||
|
||||
@JsonProperty
|
||||
private String paymentId;
|
||||
|
||||
@JsonProperty
|
||||
private String customerId;
|
||||
|
||||
@JsonProperty
|
||||
private String orderId;
|
||||
|
||||
@JsonProperty
|
||||
private BigDecimal price;
|
||||
|
||||
@JsonProperty
|
||||
private String paymentStatus;
|
||||
|
||||
@JsonProperty
|
||||
private ZonedDateTime createdAt;
|
||||
|
||||
@JsonProperty
|
||||
private List<String> failureMessages;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.food.order.system.payment.application.service.outbox.model;
|
||||
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.system.valueobject.PaymentStatus;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
public class OrderOutboxMessage {
|
||||
|
||||
private UUID id;
|
||||
|
||||
private UUID sagaId;
|
||||
|
||||
private ZonedDateTime createdAt;
|
||||
|
||||
private ZonedDateTime processedAt;
|
||||
|
||||
private String type;
|
||||
|
||||
private String payload;
|
||||
|
||||
private PaymentStatus paymentStatus;
|
||||
|
||||
@Setter
|
||||
private OutboxStatus outboxStatus;
|
||||
|
||||
private int version;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.food.order.system.payment.application.service.outbox.scheduler;
|
||||
|
||||
|
||||
import com.food.order.system.outbox.OutboxScheduler;
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.system.payment.application.service.outbox.model.OrderOutboxMessage;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class OrderOutboxCleanerScheduler implements OutboxScheduler {
|
||||
|
||||
private final OrderOutboxHelper orderOutboxHelper;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Scheduled(cron = "@midnight")
|
||||
public void processOutboxMessage() {
|
||||
Optional<List<OrderOutboxMessage>> outboxMessagesResponse =
|
||||
orderOutboxHelper.getOrderOutboxMessageByOutboxStatus(OutboxStatus.COMPLETED);
|
||||
if (outboxMessagesResponse.isPresent() && outboxMessagesResponse.get().size() > 0) {
|
||||
List<OrderOutboxMessage> outboxMessages = outboxMessagesResponse.get();
|
||||
log.info("Received {} OrderOutboxMessage for clean-up!", outboxMessages.size());
|
||||
orderOutboxHelper.deleteOrderOutboxMessageByOutboxStatus(OutboxStatus.COMPLETED);
|
||||
log.info("Deleted {} OrderOutboxMessage!", outboxMessages.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.food.order.system.payment.application.service.outbox.scheduler;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.system.payment.application.service.outbox.model.OrderEventPayload;
|
||||
import com.food.order.system.payment.application.service.outbox.model.OrderOutboxMessage;
|
||||
import com.food.order.system.payment.application.service.ports.output.repository.OrderOutboxRepository;
|
||||
import com.food.order.system.payment.application.service.exception.PaymentDomainException;
|
||||
import com.food.order.system.valueobject.PaymentStatus;
|
||||
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.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.food.order.system.DomainConstants.UTC;
|
||||
import static com.food.order.system.outbox.order.SagaConst.ORDER_PROCESSING_SAGA;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class OrderOutboxHelper {
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
private final OrderOutboxRepository orderOutboxRepository;
|
||||
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Optional<OrderOutboxMessage> getCompletedOrderOutboxMessageBySagaIdAndPaymentStatus(UUID sagaId,
|
||||
PaymentStatus
|
||||
paymentStatus) {
|
||||
return orderOutboxRepository.findByTypeAndSagaIdAndPaymentStatusAndOutboxStatus(ORDER_PROCESSING_SAGA, sagaId,
|
||||
paymentStatus, OutboxStatus.COMPLETED);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Optional<List<OrderOutboxMessage>> getOrderOutboxMessageByOutboxStatus(OutboxStatus outboxStatus) {
|
||||
return orderOutboxRepository.findByTypeAndOutboxStatus(ORDER_PROCESSING_SAGA, outboxStatus);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteOrderOutboxMessageByOutboxStatus(OutboxStatus outboxStatus) {
|
||||
orderOutboxRepository.deleteByTypeAndOutboxStatus(ORDER_PROCESSING_SAGA, outboxStatus);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void saveOrderOutboxMessage(OrderEventPayload orderEventPayload,
|
||||
PaymentStatus paymentStatus,
|
||||
OutboxStatus outboxStatus,
|
||||
UUID sagaId) {
|
||||
save(OrderOutboxMessage.builder()
|
||||
.id(UUID.randomUUID())
|
||||
.sagaId(sagaId)
|
||||
.createdAt(orderEventPayload.getCreatedAt())
|
||||
.processedAt(ZonedDateTime.now(ZoneId.of(UTC)))
|
||||
.type(ORDER_PROCESSING_SAGA)
|
||||
.payload(createPayload(orderEventPayload))
|
||||
.paymentStatus(paymentStatus)
|
||||
.outboxStatus(outboxStatus)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void updateOutboxMessage(OrderOutboxMessage orderOutboxMessage, OutboxStatus outboxStatus) {
|
||||
orderOutboxMessage.setOutboxStatus(outboxStatus);
|
||||
save(orderOutboxMessage);
|
||||
log.info("Order outbox table status is updated as: {}", outboxStatus.name());
|
||||
}
|
||||
|
||||
private String createPayload(OrderEventPayload orderEventPayload) {
|
||||
try {
|
||||
return objectMapper.writeValueAsString(orderEventPayload);
|
||||
} catch (JsonProcessingException e) {
|
||||
log.error("Could not create OrderEventPayload json!", e);
|
||||
throw new PaymentDomainException("Could not create OrderEventPayload json!", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void save(OrderOutboxMessage orderOutboxMessage) {
|
||||
OrderOutboxMessage response = orderOutboxRepository.save(orderOutboxMessage);
|
||||
if (Objects.isNull(response)) {
|
||||
log.error("Could not save OrderOutboxMessage!");
|
||||
throw new PaymentDomainException("Could not save OrderOutboxMessage!");
|
||||
}
|
||||
log.info("OrderOutboxMessage is saved with id: {}", orderOutboxMessage.getId());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.food.order.system.payment.application.service.outbox.scheduler;
|
||||
|
||||
import com.food.order.system.outbox.OutboxScheduler;
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.system.payment.application.service.outbox.model.OrderOutboxMessage;
|
||||
import com.food.order.system.payment.application.service.ports.output.message.publisher.PaymentResponseMessagePublisher;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class OrderOutboxScheduler implements OutboxScheduler {
|
||||
|
||||
private final OrderOutboxHelper orderOutboxHelper;
|
||||
private final PaymentResponseMessagePublisher paymentResponseMessagePublisher;
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Scheduled(fixedRateString = "${payment-service.outbox-scheduler-fixed-rate}",
|
||||
initialDelayString = "${payment-service.outbox-scheduler-initial-delay}")
|
||||
public void processOutboxMessage() {
|
||||
var outboxMessagesResponse =
|
||||
orderOutboxHelper.getOrderOutboxMessageByOutboxStatus(OutboxStatus.STARTED);
|
||||
if (outboxMessagesResponse.isPresent() && outboxMessagesResponse.get().size() > 0) {
|
||||
List<OrderOutboxMessage> outboxMessages = outboxMessagesResponse.get();
|
||||
log.info("Received {} OrderOutboxMessage with ids {}, sending to message bus!", outboxMessages.size(),
|
||||
outboxMessages.stream().map(outboxMessage ->
|
||||
outboxMessage.getId().toString()).collect(Collectors.joining(",")));
|
||||
outboxMessages.forEach(orderOutboxMessage ->
|
||||
paymentResponseMessagePublisher.publish(orderOutboxMessage,
|
||||
orderOutboxHelper::updateOutboxMessage));
|
||||
log.info("{} OrderOutboxMessage sent to message bus!", outboxMessages.size());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package com.food.order.system.payment.application.service.ports.output.message.publisher;
|
||||
|
||||
import com.food.order.system.payment.service.domain.event.PaymentCancelledEvent;
|
||||
import com.food.order.system.event.publisher.DomainEventPublisher;
|
||||
|
||||
public interface PaymentCancelledMessagePublisher extends DomainEventPublisher<PaymentCancelledEvent> {
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package com.food.order.system.payment.application.service.ports.output.message.publisher;
|
||||
|
||||
import com.food.order.system.payment.service.domain.event.PaymentCompletedEvent;
|
||||
import com.food.order.system.event.publisher.DomainEventPublisher;
|
||||
|
||||
public interface PaymentCompletedMessagePublisher extends DomainEventPublisher<PaymentCompletedEvent> {
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package com.food.order.system.payment.application.service.ports.output.message.publisher;
|
||||
|
||||
import com.food.order.system.payment.service.domain.event.PaymentFailedEvent;
|
||||
import com.food.order.system.event.publisher.DomainEventPublisher;
|
||||
|
||||
public interface PaymentFailedMessagePublisher extends DomainEventPublisher<PaymentFailedEvent> {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.food.order.system.payment.application.service.ports.output.message.publisher;
|
||||
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.system.payment.application.service.outbox.model.OrderOutboxMessage;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public interface PaymentResponseMessagePublisher {
|
||||
void publish(OrderOutboxMessage message,
|
||||
BiConsumer<OrderOutboxMessage , OutboxStatus> updateOutboxMessage);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.food.order.system.payment.application.service.ports.output.repository;
|
||||
|
||||
import com.food.order.system.outbox.OutboxStatus;
|
||||
import com.food.order.system.payment.application.service.outbox.model.OrderOutboxMessage;
|
||||
import com.food.order.system.valueobject.PaymentStatus;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Repository
|
||||
public interface OrderOutboxRepository {
|
||||
|
||||
OrderOutboxMessage save(OrderOutboxMessage orderOutboxMessage);
|
||||
|
||||
Optional<List<OrderOutboxMessage>> findByTypeAndOutboxStatus(String type, OutboxStatus status);
|
||||
|
||||
Optional<OrderOutboxMessage> findByTypeAndSagaIdAndPaymentStatusAndOutboxStatus(String type,
|
||||
UUID sagaId,
|
||||
PaymentStatus paymentStatus,
|
||||
OutboxStatus outboxStatus);
|
||||
void deleteByTypeAndOutboxStatus(String type, OutboxStatus status);
|
||||
|
||||
|
||||
}
|
||||
@@ -3,11 +3,7 @@ package com.food.order.system.payment.service.domain;
|
||||
import com.food.order.system.payment.service.domain.entity.CreditEntry;
|
||||
import com.food.order.system.payment.service.domain.entity.CreditHistory;
|
||||
import com.food.order.system.payment.service.domain.entity.Payment;
|
||||
import com.food.order.system.payment.service.domain.event.PaymentCancelledEvent;
|
||||
import com.food.order.system.payment.service.domain.event.PaymentCompletedEvent;
|
||||
import com.food.order.system.payment.service.domain.event.PaymentEvent;
|
||||
import com.food.order.system.payment.service.domain.event.PaymentFailedEvent;
|
||||
import com.food.order.system.event.publisher.DomainEventPublisher;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -16,14 +12,10 @@ public interface PaymentDomainService {
|
||||
PaymentEvent validateAndInitializePayment( Payment paymentEvent,
|
||||
CreditEntry creditEntry,
|
||||
List<CreditHistory> creditHistory,
|
||||
List<String> failureMessages,
|
||||
DomainEventPublisher<PaymentCompletedEvent> publisher,
|
||||
DomainEventPublisher<PaymentFailedEvent> failedEventDomainEventPublisher);
|
||||
List<String> failureMessages);
|
||||
|
||||
PaymentEvent validateAndCancelledPayment( Payment paymentEvent,
|
||||
CreditEntry creditEntry,
|
||||
List<CreditHistory> creditHistory,
|
||||
List<String> failureMessages,
|
||||
DomainEventPublisher<PaymentCancelledEvent> publisher,
|
||||
DomainEventPublisher<PaymentFailedEvent> failedEventDomainEventPublisher);
|
||||
List<String> failureMessages);
|
||||
}
|
||||
|
||||
@@ -29,9 +29,7 @@ public class PaymentDomainServiceImpl implements PaymentDomainService {
|
||||
public PaymentEvent validateAndInitializePayment(Payment payment,
|
||||
CreditEntry creditEntry,
|
||||
List<CreditHistory> creditHistory,
|
||||
List<String> failureMessages,
|
||||
DomainEventPublisher<PaymentCompletedEvent> publisher,
|
||||
DomainEventPublisher<PaymentFailedEvent> failedPublisher) {
|
||||
List<String> failureMessages) {
|
||||
payment.validatePayment(failureMessages);
|
||||
payment.initializePayment();
|
||||
validateCreditEntry(payment,creditEntry,failureMessages);
|
||||
@@ -42,11 +40,11 @@ public class PaymentDomainServiceImpl implements PaymentDomainService {
|
||||
if (failureMessages.isEmpty()) {
|
||||
log.info("Payment is valid and initialized");
|
||||
payment.updateStatus(PaymentStatus.COMPLETED);
|
||||
return new PaymentCompletedEvent(payment, ZonedDateTime.now(ZoneId.of(UTC)),publisher );
|
||||
return new PaymentCompletedEvent(payment, ZonedDateTime.now(ZoneId.of(UTC)) );
|
||||
} else {
|
||||
log.info("Payment is invalid and not initialized");
|
||||
payment.updateStatus(PaymentStatus.FAILED);
|
||||
return new PaymentFailedEvent(payment, ZonedDateTime.now(ZoneId.of(UTC)), failureMessages,failedPublisher);
|
||||
return new PaymentFailedEvent(payment, ZonedDateTime.now(ZoneId.of(UTC)), failureMessages);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -55,9 +53,7 @@ public class PaymentDomainServiceImpl implements PaymentDomainService {
|
||||
public PaymentEvent validateAndCancelledPayment(Payment payment,
|
||||
CreditEntry creditEntry,
|
||||
List<CreditHistory> creditHistory,
|
||||
List<String> failureMessages,
|
||||
DomainEventPublisher<PaymentCancelledEvent> publisher,
|
||||
DomainEventPublisher<PaymentFailedEvent> failedPublisher) {
|
||||
List<String> failureMessages) {
|
||||
|
||||
payment.validatePayment(failureMessages);
|
||||
addCreditEntry(payment,creditEntry);
|
||||
@@ -66,11 +62,11 @@ public class PaymentDomainServiceImpl implements PaymentDomainService {
|
||||
if (failureMessages.isEmpty()) {
|
||||
log.info("Payment is valid and cancelled");
|
||||
payment.updateStatus(PaymentStatus.CANCELED);
|
||||
return new PaymentCancelledEvent(payment, ZonedDateTime.now(ZoneId.of(UTC)),publisher);
|
||||
return new PaymentCancelledEvent(payment, ZonedDateTime.now(ZoneId.of(UTC)));
|
||||
} else {
|
||||
log.info("Payment is invalid and not cancelled");
|
||||
payment.updateStatus(PaymentStatus.FAILED);
|
||||
return new PaymentFailedEvent(payment, ZonedDateTime.now(ZoneId.of(UTC)), failureMessages,failedPublisher);
|
||||
return new PaymentFailedEvent(payment, ZonedDateTime.now(ZoneId.of(UTC)), failureMessages);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +1,15 @@
|
||||
package com.food.order.system.payment.service.domain.event;
|
||||
|
||||
import com.food.order.system.payment.service.domain.entity.Payment;
|
||||
import com.food.order.system.event.publisher.DomainEventPublisher;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Collections;
|
||||
|
||||
public class PaymentCancelledEvent extends PaymentEvent{
|
||||
|
||||
private final DomainEventPublisher<PaymentCancelledEvent> publisher;
|
||||
|
||||
public PaymentCancelledEvent(Payment payment, ZonedDateTime createdAt, DomainEventPublisher<PaymentCancelledEvent> publisher) {
|
||||
public PaymentCancelledEvent(Payment payment, ZonedDateTime createdAt) {
|
||||
super(payment, createdAt, Collections.emptyList());
|
||||
this.publisher = publisher;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void fire() {
|
||||
publisher.publish(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,18 +8,10 @@ import java.util.Collections;
|
||||
|
||||
public class PaymentCompletedEvent extends PaymentEvent{
|
||||
|
||||
private final DomainEventPublisher<PaymentCompletedEvent> publisher;
|
||||
|
||||
public PaymentCompletedEvent(Payment payment,
|
||||
ZonedDateTime createdAt,
|
||||
DomainEventPublisher<PaymentCompletedEvent> publisher) {
|
||||
ZonedDateTime createdAt) {
|
||||
super(payment, createdAt , Collections.emptyList());
|
||||
this.publisher = publisher;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void fire() {
|
||||
publisher.publish(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,15 @@
|
||||
package com.food.order.system.payment.service.domain.event;
|
||||
|
||||
import com.food.order.system.payment.service.domain.entity.Payment;
|
||||
import com.food.order.system.event.publisher.DomainEventPublisher;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.List;
|
||||
|
||||
public class PaymentFailedEvent extends PaymentEvent{
|
||||
|
||||
private final DomainEventPublisher<PaymentFailedEvent> publisher;
|
||||
|
||||
public PaymentFailedEvent(Payment payment, ZonedDateTime createdAt, List<String> failureMessages,
|
||||
DomainEventPublisher<PaymentFailedEvent> publisher) {
|
||||
public PaymentFailedEvent(Payment payment, ZonedDateTime createdAt, List<String> failureMessages) {
|
||||
super(payment, createdAt, failureMessages);
|
||||
this.publisher = publisher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fire() {
|
||||
publisher.publish(this);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user