Outbox Message and Scheduler class implemented part - 3.

This commit is contained in:
Ali CANLI
2022-07-16 14:01:49 +03:00
parent 3affe7ccdd
commit 9ff94746f6
153 changed files with 961 additions and 525 deletions

View File

@@ -1,4 +1,4 @@
package com.food.order.sysyem;
package com.food.order.system;
public class DomainConstants {

View File

@@ -1,4 +1,4 @@
package com.food.order.sysyem.entity;
package com.food.order.system.entity;
public abstract class AggregateRoot<ID> extends BaseEntity<ID> {

View File

@@ -1,4 +1,4 @@
package com.food.order.sysyem.entity;
package com.food.order.system.entity;
public abstract class BaseEntity<ID> {
private ID id;

View File

@@ -1,4 +1,4 @@
package com.food.order.sysyem.event;
package com.food.order.system.event;
// Base Domain Event Generic Class

View File

@@ -1,6 +1,6 @@
package com.food.order.sysyem.event.publisher;
package com.food.order.system.event.publisher;
import com.food.order.sysyem.event.DomainEvent;
import com.food.order.system.event.DomainEvent;
public interface DomainEventPublisher <T extends DomainEvent> {
void publish(T event);

View File

@@ -1,4 +1,4 @@
package com.food.order.sysyem.exception;
package com.food.order.system.exception;
public class DomainException extends RuntimeException {

View File

@@ -1,4 +1,4 @@
package com.food.order.sysyem.valueobject;
package com.food.order.system.valueobject;
public abstract class BaseId<T> {

View File

@@ -1,4 +1,4 @@
package com.food.order.sysyem.valueobject;
package com.food.order.system.valueobject;
import java.util.UUID;

View File

@@ -1,4 +1,4 @@
package com.food.order.sysyem.valueobject;
package com.food.order.system.valueobject;
import java.math.BigDecimal;
import java.math.RoundingMode;

View File

@@ -1,4 +1,4 @@
package com.food.order.sysyem.valueobject;
package com.food.order.system.valueobject;
public enum OrderApprovalStatus {
APPROVED,

View File

@@ -1,4 +1,4 @@
package com.food.order.sysyem.valueobject;
package com.food.order.system.valueobject;
import java.util.UUID;

View File

@@ -1,4 +1,4 @@
package com.food.order.sysyem.valueobject;
package com.food.order.system.valueobject;
public enum OrderStatus {
PENDING,

View File

@@ -1,4 +1,4 @@
package com.food.order.sysyem.valueobject;
package com.food.order.system.valueobject;
public enum PaymentOrderStatus {
PENDING,

View File

@@ -1,4 +1,4 @@
package com.food.order.sysyem.valueobject;
package com.food.order.system.valueobject;
public enum PaymentStatus {
COMPLETED,CANCELED,FAILED

View File

@@ -1,4 +1,4 @@
package com.food.order.sysyem.valueobject;
package com.food.order.system.valueobject;
import java.util.UUID;

View File

@@ -1,4 +1,4 @@
package com.food.order.sysyem.valueobject;
package com.food.order.system.valueobject;
import java.util.UUID;

View File

@@ -1,4 +1,4 @@
package com.food.order.sysyem.valueobject;
package com.food.order.system.valueobject;
public enum RestaurantOrderStatus {
PAID

View File

@@ -1,14 +0,0 @@
package com.food.order.sysyem.event;
public final class EmptyEvent implements DomainEvent<Void> {
public static final EmptyEvent INSTANCE = new EmptyEvent();
private EmptyEvent() {
}
@Override
public void fire() {
}
}

View File

@@ -41,6 +41,10 @@
<groupId>io.confluent</groupId>
<artifactId>kafka-avro-serializer</artifactId>
</dependency>
<dependency>
<groupId>com.food.order</groupId>
<artifactId>outbox</artifactId>
</dependency>
</dependencies>

View File

@@ -1,34 +1,59 @@
package com.food.order.system.kafka.producer;
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 lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.producer.RecordMetadata;
import org.springframework.kafka.support.SendResult;
import org.springframework.stereotype.Component;
import org.springframework.util.concurrent.ListenableFutureCallback;
import java.util.function.BiConsumer;
@Component
@Slf4j
@RequiredArgsConstructor
public class KafkaMessageHelper {
public <T> ListenableFutureCallback<SendResult<String, T>> getKafkaCallBack
(String responseTopicName, T t,String orderId, String requestAvroModelName) {
return new ListenableFutureCallback<>() {
private final ObjectMapper objectMapper;
public <T, U> ListenableFutureCallback<SendResult<String, T>>
getKafkaCallback(String responseTopicName, T avroModel, U outboxMessage,
BiConsumer<U, OutboxStatus> outboxCallback,
String orderId, String avroModelName) {
return new ListenableFutureCallback<SendResult<String, T>>() {
@Override
public void onFailure(Throwable ex) {
log.error("Error while sending " + requestAvroModelName +
" to " + responseTopicName + " for orderId " + orderId, ex);
log.error("Error while sending {} with message: {} and outbox type: {} to topic {}",
avroModelName, avroModel.toString(), outboxMessage.getClass().getName(), responseTopicName, ex);
outboxCallback.accept(outboxMessage, OutboxStatus.FAILED);
}
@Override
public void onSuccess(SendResult<String, T> result) {
RecordMetadata recordMetadata = result.getRecordMetadata();
log.info("Received successful response from kafka for order id : {} Topic : {} Partition : {} , Offset : {} , Timestamp : {}",
RecordMetadata metadata = result.getRecordMetadata();
log.info("Received successful response from Kafka for order id: {}" +
" Topic: {} Partition: {} Offset: {} Timestamp: {}",
orderId,
recordMetadata.topic(),
recordMetadata.partition(),
recordMetadata.offset(),
recordMetadata.timestamp());
metadata.topic(),
metadata.partition(),
metadata.offset(),
metadata.timestamp());
outboxCallback.accept(outboxMessage, OutboxStatus.COMPLETED);
}
};
}
public <T> T getOrderEventPayload(String payload, Class<T> outputType) {
try {
return objectMapper.readValue(payload, outputType);
} catch (JsonProcessingException e) {
log.error("Could not read {} object!", outputType.getName(), e);
throw new OrderDomainException("Could not read " + outputType.getName() + " object!", e);
}
}
}

View File

@@ -1,10 +1,10 @@
package com.food.order.system.service.app.api;
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.http.ResponseEntity;

View File

@@ -1,4 +1,4 @@
package com.food.order.system.order.domain;
package com.food.order.system;
import com.food.order.system.domain.service.OrderDomainService;
import com.food.order.system.domain.service.impl.OrderDomainServiceImpl;

View File

@@ -1,4 +1,4 @@
package com.food.order.system.order.domain;
package com.food.order.system;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

View File

@@ -1,6 +1,6 @@
package com.food.order.system.data.access.customer.adapter;
import com.food.order.sysyem.ports.output.repository.CustomerRepository;
import com.food.order.system.ports.output.repository.CustomerRepository;
import com.food.order.system.data.access.customer.mapper.CustomerDataAccessMapper;
import com.food.order.system.data.access.customer.repository.CustomerJPARepository;
import com.food.order.system.domain.entity.Customer;

View File

@@ -1,6 +1,6 @@
package com.food.order.system.data.access.customer.mapper;
import com.food.order.sysyem.valueobject.CustomerId;
import com.food.order.system.valueobject.CustomerId;
import com.food.order.system.data.access.customer.entity.CustomerEntity;
import com.food.order.system.domain.entity.Customer;
import org.springframework.stereotype.Component;

View File

@@ -1,6 +1,6 @@
package com.food.order.system.data.access.order.adapter;
import com.food.order.sysyem.ports.output.repository.OrderRepository;
import com.food.order.system.ports.output.repository.OrderRepository;
import com.food.order.system.data.access.order.mapper.OrderDataAccessMapper;
import com.food.order.system.data.access.order.repository.OrderJpaRepository;
import com.food.order.system.domain.entity.Order;

View File

@@ -1,6 +1,6 @@
package com.food.order.system.data.access.order.entity;
import com.food.order.sysyem.valueobject.OrderStatus;
import com.food.order.system.valueobject.OrderStatus;
import lombok.*;
import org.hibernate.annotations.DynamicUpdate;

View File

@@ -9,7 +9,7 @@ import com.food.order.system.domain.entity.Product;
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 org.springframework.stereotype.Component;
import java.util.ArrayList;

View File

@@ -5,8 +5,8 @@ import com.food.order.system.data.access.outbox.payment.mapper.PaymentOutboxData
import com.food.order.system.data.access.outbox.payment.repository.PaymentOutboxJpaRepository;
import com.food.order.system.outbox.OutboxStatus;
import com.food.order.system.saga.SagaStatus;
import com.food.order.sysyem.outbox.model.payment.OrderPaymentOutboxMessage;
import com.food.order.sysyem.ports.output.repository.PaymentOutboxRepository;
import com.food.order.system.outbox.model.payment.OrderPaymentOutboxMessage;
import com.food.order.system.ports.output.repository.PaymentOutboxRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

View File

@@ -3,7 +3,7 @@ package com.food.order.system.data.access.outbox.payment.entity;
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.*;
import javax.persistence.*;

View File

@@ -1,7 +1,7 @@
package com.food.order.system.data.access.outbox.payment.mapper;
import com.food.order.system.data.access.outbox.payment.entity.PaymentOutboxEntity;
import com.food.order.sysyem.outbox.model.payment.OrderPaymentOutboxMessage;
import com.food.order.system.outbox.model.payment.OrderPaymentOutboxMessage;
import org.springframework.stereotype.Component;
@Component

View File

@@ -6,8 +6,8 @@ import com.food.order.system.data.access.outbox.restaurantapproval.mapper.Approv
import com.food.order.system.data.access.outbox.restaurantapproval.repository.ApprovalOutboxJpaRepository;
import com.food.order.system.outbox.OutboxStatus;
import com.food.order.system.saga.SagaStatus;
import com.food.order.sysyem.outbox.model.approval.OrderApprovalOutboxMessage;
import com.food.order.sysyem.ports.output.repository.ApprovalOutboxRepository;
import com.food.order.system.outbox.model.approval.OrderApprovalOutboxMessage;
import com.food.order.system.ports.output.repository.ApprovalOutboxRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

View File

@@ -2,7 +2,7 @@ package com.food.order.system.data.access.outbox.restaurantapproval.entity;
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.*;
import javax.persistence.*;

View File

@@ -1,7 +1,7 @@
package com.food.order.system.data.access.outbox.restaurantapproval.mapper;
import com.food.order.system.data.access.outbox.restaurantapproval.entity.ApprovalOutboxEntity;
import com.food.order.sysyem.outbox.model.approval.OrderApprovalOutboxMessage;
import com.food.order.system.outbox.model.approval.OrderApprovalOutboxMessage;
import org.springframework.stereotype.Component;
@Component

View File

@@ -3,7 +3,7 @@ package com.food.order.system.data.access.restaurant.adapter;
import com.food.order.system.common.data.access.repository.RestaurantJpaRepository;
import com.food.order.system.data.access.restaurant.mapper.RestaurantDataAccessMapper;
import com.food.order.system.domain.entity.Restaurant;
import com.food.order.sysyem.ports.output.repository.RestaurantRepository;
import com.food.order.system.ports.output.repository.RestaurantRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

View File

@@ -4,9 +4,9 @@ import com.food.order.system.common.data.access.entity.RestaurantEntity;
import com.food.order.system.common.data.access.exception.RestaurantDataAccessException;
import com.food.order.system.domain.entity.Product;
import com.food.order.system.domain.entity.Restaurant;
import com.food.order.sysyem.valueobject.Money;
import com.food.order.sysyem.valueobject.ProductId;
import com.food.order.sysyem.valueobject.RestaurantId;
import com.food.order.system.valueobject.Money;
import com.food.order.system.valueobject.ProductId;
import com.food.order.system.valueobject.RestaurantId;
import org.springframework.stereotype.Component;
import java.util.List;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -1,4 +1,4 @@
package com.food.order.sysyem.dto.create;
package com.food.order.system.dto.create;
import lombok.AllArgsConstructor;
import lombok.Builder;

View File

@@ -1,4 +1,4 @@
package com.food.order.sysyem.dto.create;
package com.food.order.system.dto.create;
import lombok.Builder;
import lombok.Getter;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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()

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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())

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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(),

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

@@ -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!");
}
}
}

View File

@@ -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();
}
}

View File

@@ -0,0 +1,3 @@
order-service:
outbox-scheduler-fixed-rate: 10000
outbox-scheduler-initial-delay: 10000

View File

@@ -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> {

View File

@@ -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;

View File

@@ -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> {

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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> {

View File

@@ -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;

View File

@@ -1,10 +1,10 @@
package com.food.order.system.order.messaging.listener.kafka;
package com.food.order.system.messaging.listener.kafka;
import com.food.order.system.kafka.consumer.KafkaConsumer;
import com.food.order.system.kafka.order.avro.model.PaymentResponseAvroModel;
import com.food.order.system.kafka.order.avro.model.PaymentStatus;
import com.food.order.system.order.messaging.mapper.OrderMessagingDataMapper;
import com.food.order.sysyem.ports.input.message.listener.payment.PaymentResponseMessageListener;
import com.food.order.system.messaging.mapper.OrderMessagingDataMapper;
import com.food.order.system.ports.input.message.listener.payment.PaymentResponseMessageListener;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.kafka.annotation.KafkaListener;

View File

@@ -1,10 +1,10 @@
package com.food.order.system.order.messaging.listener.kafka;
package com.food.order.system.messaging.listener.kafka;
import com.food.order.system.kafka.consumer.KafkaConsumer;
import com.food.order.system.kafka.order.avro.model.OrderApprovalStatus;
import com.food.order.system.kafka.order.avro.model.RestaurantApprovalResponseAvroModel;
import com.food.order.system.order.messaging.mapper.OrderMessagingDataMapper;
import com.food.order.sysyem.ports.input.message.listener.restaurantapproval.RestaurantApprovalResponseMessageListener;
import com.food.order.system.messaging.mapper.OrderMessagingDataMapper;
import com.food.order.system.ports.input.message.listener.restaurantapproval.RestaurantApprovalResponseMessageListener;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.kafka.annotation.KafkaListener;

View File

@@ -1,13 +1,15 @@
package com.food.order.system.order.messaging.mapper;
package com.food.order.system.messaging.mapper;
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.kafka.order.avro.model.*;
import com.food.order.sysyem.dto.message.PaymentResponse;
import com.food.order.sysyem.dto.message.RestaurantApprovalResponse;
import com.food.order.sysyem.valueobject.OrderApprovalStatus;
import com.food.order.sysyem.valueobject.PaymentStatus;
import com.food.order.system.dto.message.PaymentResponse;
import com.food.order.system.dto.message.RestaurantApprovalResponse;
import com.food.order.system.outbox.model.approval.OrderApprovalEventPayload;
import com.food.order.system.outbox.model.payment.OrderPaymentEventPayload;
import com.food.order.system.valueobject.OrderApprovalStatus;
import com.food.order.system.valueobject.PaymentStatus;
import org.springframework.stereotype.Component;
import java.util.UUID;
@@ -87,4 +89,38 @@ public class OrderMessagingDataMapper {
.failureMessages(message.getFailureMessages())
.build();
}
public RestaurantApprovalRequestAvroModel
orderApprovalEventToRestaurantApprovalRequestAvroModel(String sagaId, OrderApprovalEventPayload
orderApprovalEventPayload) {
return RestaurantApprovalRequestAvroModel.newBuilder()
.setId(UUID.randomUUID().toString())
.setSagaId(sagaId)
.setOrderId(orderApprovalEventPayload.getOrderId())
.setRestaurantId(orderApprovalEventPayload.getRestaurantId())
.setRestaurantOrderStatus(RestaurantOrderStatus
.valueOf(orderApprovalEventPayload.getRestaurantOrderStatus()))
.setProducts(orderApprovalEventPayload.getProducts().stream().map(orderApprovalEventProduct ->
Product.newBuilder()
.setId(orderApprovalEventProduct.getId())
.setQuantity(orderApprovalEventProduct.getQuantity())
.build()).toList())
.setPrice(orderApprovalEventPayload.getPrice())
.setCreatedAt(orderApprovalEventPayload.getCreatedAt().toInstant())
.build();
}
public PaymentRequestAvroModel orderPaymentEventToPaymentRequestAvroModel(String sagaId, OrderPaymentEventPayload orderPaymentEventPayload) {
return PaymentRequestAvroModel.newBuilder()
.setId(UUID.randomUUID().toString())
.setSagaId(sagaId)
.setCustomerId(orderPaymentEventPayload.getCustomerId())
.setOrderId(orderPaymentEventPayload.getOrderId())
.setPrice(orderPaymentEventPayload.getPrice())
.setCreatedAt(orderPaymentEventPayload.getCreatedAt().toInstant())
.setPaymentOrderStatus(PaymentOrderStatus.valueOf(orderPaymentEventPayload.getPaymentOrderStatus()))
.build();
}
}

View File

@@ -0,0 +1,69 @@
package com.food.order.system.messaging.publisher.kafka;
import com.food.order.system.kafka.order.avro.model.RestaurantApprovalRequestAvroModel;
import com.food.order.system.kafka.producer.KafkaMessageHelper;
import com.food.order.system.kafka.producer.service.KafkaProducer;
import com.food.order.system.messaging.mapper.OrderMessagingDataMapper;
import com.food.order.system.outbox.OutboxStatus;
import com.food.order.system.config.OrderServiceConfigData;
import com.food.order.system.outbox.model.approval.OrderApprovalEventPayload;
import com.food.order.system.outbox.model.approval.OrderApprovalOutboxMessage;
import com.food.order.system.ports.output.message.publisher.restaurantapproval.RestaurantApprovalRequestMessagePublisher;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.function.BiConsumer;
@Slf4j
@Component
@RequiredArgsConstructor
public class OrderApprovalEventKafkaPublisher implements RestaurantApprovalRequestMessagePublisher {
private final OrderMessagingDataMapper orderMessagingDataMapper;
private final KafkaProducer<String, RestaurantApprovalRequestAvroModel> kafkaProducer;
private final OrderServiceConfigData orderServiceConfigData;
private final KafkaMessageHelper kafkaMessageHelper;
@Override
public void publish(OrderApprovalOutboxMessage orderApprovalOutboxMessage,
BiConsumer<OrderApprovalOutboxMessage, OutboxStatus> outboxCallback) {
OrderApprovalEventPayload orderApprovalEventPayload =
kafkaMessageHelper.getOrderEventPayload(orderApprovalOutboxMessage.getPayload(),
OrderApprovalEventPayload.class);
String sagaId = orderApprovalOutboxMessage.getSagaId().toString();
log.info("Received OrderApprovalOutboxMessage for order id: {} and saga id: {}",
orderApprovalEventPayload.getOrderId(),
sagaId);
try {
RestaurantApprovalRequestAvroModel restaurantApprovalRequestAvroModel =
orderMessagingDataMapper
.orderApprovalEventToRestaurantApprovalRequestAvroModel(sagaId,
orderApprovalEventPayload);
kafkaProducer.send(orderServiceConfigData.getRestaurantApprovalRequestTopicName(),
sagaId,
restaurantApprovalRequestAvroModel,
kafkaMessageHelper.getKafkaCallback(orderServiceConfigData.getRestaurantApprovalRequestTopicName(),
restaurantApprovalRequestAvroModel,
orderApprovalOutboxMessage,
outboxCallback,
orderApprovalEventPayload.getOrderId(),
"RestaurantApprovalRequestAvroModel"));
log.info("OrderApprovalEventPayload sent to kafka for order id: {} and saga id: {}",
restaurantApprovalRequestAvroModel.getOrderId(), sagaId);
} catch (Exception e) {
log.error("Error while sending OrderApprovalEventPayload to kafka for order id: {} and saga id: {}," +
" error: {}", orderApprovalEventPayload.getOrderId(), sagaId, e.getMessage());
}
}
}

View File

@@ -0,0 +1,66 @@
package com.food.order.system.messaging.publisher.kafka;
import com.food.order.system.kafka.order.avro.model.PaymentRequestAvroModel;
import com.food.order.system.kafka.producer.KafkaMessageHelper;
import com.food.order.system.kafka.producer.service.KafkaProducer;
import com.food.order.system.messaging.mapper.OrderMessagingDataMapper;
import com.food.order.system.outbox.OutboxStatus;
import com.food.order.system.config.OrderServiceConfigData;
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.message.publisher.payment.PaymentRequestMessagePublisher;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.function.BiConsumer;
@Slf4j
@Component
@RequiredArgsConstructor
public class OrderPaymentEventKafkaPublisher implements PaymentRequestMessagePublisher {
private final OrderMessagingDataMapper orderMessagingDataMapper;
private final KafkaProducer<String, PaymentRequestAvroModel> kafkaProducer;
private final OrderServiceConfigData orderServiceConfigData;
private final KafkaMessageHelper kafkaMessageHelper;
@Override
public void publish(OrderPaymentOutboxMessage orderPaymentOutboxMessage,
BiConsumer<OrderPaymentOutboxMessage, OutboxStatus> outboxCallback) {
OrderPaymentEventPayload orderPaymentEventPayload =
kafkaMessageHelper.getOrderEventPayload(orderPaymentOutboxMessage.getPayload(),
OrderPaymentEventPayload.class);
String sagaId = orderPaymentOutboxMessage.getSagaId().toString();
log.info("Received OrderPaymentOutboxMessage for order id: {} and saga id: {}",
orderPaymentEventPayload.getOrderId(),
sagaId);
try {
PaymentRequestAvroModel paymentRequestAvroModel = orderMessagingDataMapper
.orderPaymentEventToPaymentRequestAvroModel(sagaId, orderPaymentEventPayload);
kafkaProducer.send(orderServiceConfigData.getPaymentRequestTopicName(),
sagaId,
paymentRequestAvroModel,
kafkaMessageHelper.getKafkaCallback(orderServiceConfigData.getPaymentRequestTopicName(),
paymentRequestAvroModel,
orderPaymentOutboxMessage,
outboxCallback,
orderPaymentEventPayload.getOrderId(),
"PaymentRequestAvroModel"));
log.info("OrderPaymentEventPayload sent to Kafka for order id: {} and saga id: {}",
orderPaymentEventPayload.getOrderId(), sagaId);
} catch (Exception e) {
log.error("Error while sending OrderPaymentEventPayload" +
" to kafka with order id: {} and saga id: {}, error: {}",
orderPaymentEventPayload.getOrderId(), sagaId, e.getMessage());
}
}
}

View File

@@ -1,54 +0,0 @@
package com.food.order.system.order.messaging.publisher.kafka;
import com.food.order.system.domain.event.OrderCancelledEvent;
import com.food.order.system.kafka.order.avro.model.PaymentRequestAvroModel;
import com.food.order.system.kafka.producer.KafkaMessageHelper;
import com.food.order.system.kafka.producer.service.KafkaProducer;
import com.food.order.system.order.messaging.mapper.OrderMessagingDataMapper;
import com.food.order.sysyem.config.OrderServiceConfigData;
import com.food.order.sysyem.event.publisher.DomainEventPublisher;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@RequiredArgsConstructor
@Slf4j
@Component
public class CancelOrderKafkaMessagePublisher implements DomainEventPublisher<OrderCancelledEvent> {
private final OrderMessagingDataMapper orderMessagingDataMapper;
private final OrderServiceConfigData configData;
private final KafkaProducer<String, PaymentRequestAvroModel> kafkaProducer;
private final KafkaMessageHelper kafkaMessageHelper;
@Override
public void publish(OrderCancelledEvent event) {
var orderId = event.getOrder().getId().getValue().toString();
log.info("Publishing order cancel event for order id: {}", orderId);
try{
var paymentRequestAvroModel =
orderMessagingDataMapper.orderCancelledEventToPaymentRequestAvroModel(event);
kafkaProducer.send(
configData.getPaymentRequestTopicName(),
orderId,
paymentRequestAvroModel,
kafkaMessageHelper.getKafkaCallBack(configData.getPaymentRequestTopicName()
,paymentRequestAvroModel,
orderId,
"PaymentRequestAvroModel"));
log.info("Published order cancel event for order id: {}", orderId);
}
catch(Exception e){
log.error("Error publishing order cancel event for order id: {}", orderId, e);
}
}
}

View File

@@ -1,52 +0,0 @@
package com.food.order.system.order.messaging.publisher.kafka;
import com.food.order.system.domain.event.OrderCreatedEvent;
import com.food.order.system.kafka.order.avro.model.PaymentRequestAvroModel;
import com.food.order.system.kafka.producer.KafkaMessageHelper;
import com.food.order.system.kafka.producer.service.KafkaProducer;
import com.food.order.system.order.messaging.mapper.OrderMessagingDataMapper;
import com.food.order.sysyem.config.OrderServiceConfigData;
import com.food.order.sysyem.event.publisher.DomainEventPublisher;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Component
@Slf4j
@RequiredArgsConstructor
public class CreateOrderKafkaMessagePublisher implements DomainEventPublisher<OrderCreatedEvent> {
private final OrderMessagingDataMapper orderMessagingDataMapper;
private final OrderServiceConfigData configData;
private final KafkaProducer<String, PaymentRequestAvroModel> kafkaProducer;
private final KafkaMessageHelper kafkaMessageHelper;
@Override
public void publish(OrderCreatedEvent event) {
var orderId = event.getOrder().getId().getValue().toString();
log.info("Publishing order created event for order id: {}", orderId);
try{
var paymentRequestAvroModel =
orderMessagingDataMapper.orderCreatedEventToPaymentRequestAvroModel(event);
kafkaProducer.send(
configData.getPaymentRequestTopicName(),
orderId,
paymentRequestAvroModel,
kafkaMessageHelper.getKafkaCallBack(configData.getPaymentRequestTopicName(),
paymentRequestAvroModel,
orderId,
"PaymentRequestAvroModel"));
log.info("Published order created event for order id: {}", orderId);
}
catch(Exception e){
log.error("Error publishing order created event for order id: {} and message is {}", orderId, e.getMessage(), e);
}
}
}

Some files were not shown because too many files have changed in this diff Show More