├── delivery-ms ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── delivery │ │ │ └── ms │ │ │ ├── DeliveryMsApplication.java │ │ │ ├── controller │ │ │ └── DeliveryController.java │ │ │ ├── dto │ │ │ ├── CustomerOrder.java │ │ │ └── DeliveryEvent.java │ │ │ └── entity │ │ │ ├── Delivery.java │ │ │ └── DeliveryRepository.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── shipment │ └── microservice │ └── MicroserviceApplicationTests.java ├── order-ms ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── order │ │ │ └── ms │ │ │ ├── OrderMsApplication.java │ │ │ ├── controller │ │ │ └── OrderController.java │ │ │ ├── dto │ │ │ ├── CustomerOrder.java │ │ │ ├── OrderEvent.java │ │ │ └── Payment.java │ │ │ ├── entity │ │ │ ├── Order.java │ │ │ └── OrderRepository.java │ │ │ └── service │ │ │ └── ReverseOrder.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── order │ └── microservice │ └── MicroserviceApplicationTests.java ├── payment-ms ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── payment │ │ │ └── ms │ │ │ ├── PaymentMsApplication.java │ │ │ ├── controller │ │ │ └── PaymentController.java │ │ │ ├── dto │ │ │ ├── CustomerOrder.java │ │ │ ├── OrderEvent.java │ │ │ ├── PaymentEvent.java │ │ │ └── Stock.java │ │ │ ├── entity │ │ │ ├── Payment.java │ │ │ └── PaymentRepository.java │ │ │ └── service │ │ │ └── ReversePayment.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── payment │ └── microservice │ └── MicroserviceApplicationTests.java └── stock-ms ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── stock │ │ └── ms │ │ ├── StockMsApplication.java │ │ ├── controller │ │ └── StockController.java │ │ ├── dto │ │ ├── CustomerOrder.java │ │ ├── DeliveryEvent.java │ │ ├── PaymentEvent.java │ │ └── Stock.java │ │ ├── entity │ │ ├── StockRepository.java │ │ └── WareHouse.java │ │ └── service │ │ └── ReversesStock.java └── resources │ └── application.properties └── test └── java └── com └── inventory └── microservice └── MicroserviceApplicationTests.java /delivery-ms/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.boot 8 | spring-boot-starter-parent 9 | 3.1.1 10 | 11 | 12 | com.sc 13 | delivery-ms 14 | 0.0.1-SNAPSHOT 15 | delivery-ms 16 | Demo project for Spring Boot 17 | 18 | 17 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-data-jpa 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-web 28 | 29 | 30 | org.projectlombok 31 | lombok 32 | 33 | 34 | 35 | com.h2database 36 | h2 37 | runtime 38 | 39 | 40 | 41 | org.springframework.kafka 42 | spring-kafka 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-starter-test 47 | test 48 | 49 | 50 | 51 | 52 | 53 | 54 | org.springframework.boot 55 | spring-boot-maven-plugin 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /delivery-ms/src/main/java/com/delivery/ms/DeliveryMsApplication.java: -------------------------------------------------------------------------------- 1 | package com.delivery.ms; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DeliveryMsApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(DeliveryMsApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /delivery-ms/src/main/java/com/delivery/ms/controller/DeliveryController.java: -------------------------------------------------------------------------------- 1 | package com.delivery.ms.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.kafka.annotation.KafkaListener; 5 | import org.springframework.kafka.core.KafkaTemplate; 6 | 7 | import org.springframework.stereotype.Controller; 8 | 9 | import com.delivery.ms.dto.CustomerOrder; 10 | import com.delivery.ms.dto.DeliveryEvent; 11 | import com.delivery.ms.entity.Delivery; 12 | import com.delivery.ms.entity.DeliveryRepository; 13 | import com.fasterxml.jackson.core.JsonProcessingException; 14 | import com.fasterxml.jackson.databind.JsonMappingException; 15 | import com.fasterxml.jackson.databind.ObjectMapper; 16 | 17 | @Controller 18 | public class DeliveryController { 19 | 20 | @Autowired 21 | private DeliveryRepository repository; 22 | 23 | @Autowired 24 | private KafkaTemplate kafkaTemplate; 25 | 26 | @KafkaListener(topics = "new-stock", groupId = "stock-group") 27 | public void deliverOrder(String event) throws JsonMappingException, JsonProcessingException { 28 | System.out.println("Inside ship order for order "+event); 29 | 30 | Delivery shipment = new Delivery(); 31 | DeliveryEvent inventoryEvent = new ObjectMapper().readValue(event, DeliveryEvent.class); 32 | CustomerOrder order = inventoryEvent.getOrder(); 33 | 34 | try { 35 | if (order.getAddress() == null) { 36 | throw new Exception("Address not present"); 37 | } 38 | 39 | shipment.setAddress(order.getAddress()); 40 | shipment.setOrderId(order.getOrderId()); 41 | 42 | shipment.setStatus("success"); 43 | 44 | repository.save(shipment); 45 | } catch (Exception e) { 46 | shipment.setOrderId(order.getOrderId()); 47 | shipment.setStatus("failed"); 48 | repository.save(shipment); 49 | 50 | System.out.println(order); 51 | 52 | DeliveryEvent reverseEvent = new DeliveryEvent(); 53 | reverseEvent.setType("STOCK_REVERSED"); 54 | reverseEvent.setOrder(order); 55 | kafkaTemplate.send("reversed-stock", reverseEvent); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /delivery-ms/src/main/java/com/delivery/ms/dto/CustomerOrder.java: -------------------------------------------------------------------------------- 1 | package com.delivery.ms.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | @Getter 8 | @Setter 9 | @ToString 10 | public class CustomerOrder { 11 | 12 | private String item; 13 | 14 | private int quantity; 15 | 16 | private double amount; 17 | 18 | private String paymentMode; 19 | 20 | private Long orderId; 21 | 22 | private String address; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /delivery-ms/src/main/java/com/delivery/ms/dto/DeliveryEvent.java: -------------------------------------------------------------------------------- 1 | package com.delivery.ms.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class DeliveryEvent { 9 | 10 | private String type; 11 | 12 | private CustomerOrder order; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /delivery-ms/src/main/java/com/delivery/ms/entity/Delivery.java: -------------------------------------------------------------------------------- 1 | package com.delivery.ms.entity; 2 | 3 | import jakarta.persistence.Column; 4 | import jakarta.persistence.Entity; 5 | import jakarta.persistence.GeneratedValue; 6 | import jakarta.persistence.Id; 7 | import lombok.Getter; 8 | import lombok.Setter; 9 | 10 | @Getter 11 | @Setter 12 | @Entity 13 | public class Delivery { 14 | 15 | @Id 16 | @GeneratedValue 17 | private Long id; 18 | 19 | @Column 20 | private String address; 21 | 22 | @Column 23 | private String status; 24 | 25 | @Column 26 | private long orderId; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /delivery-ms/src/main/java/com/delivery/ms/entity/DeliveryRepository.java: -------------------------------------------------------------------------------- 1 | package com.delivery.ms.entity; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | public interface DeliveryRepository extends CrudRepository { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /delivery-ms/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port = 8083 2 | spring.h2.console.enabled=true 3 | spring.datasource.url=jdbc:h2:mem:deliverydb 4 | 5 | spring.kafka.bootstrap-servers=localhost:9092 6 | spring.kafka.consumer.group-id=delivery-group 7 | spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer 8 | spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /delivery-ms/src/test/java/com/shipment/microservice/MicroserviceApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.shipment.microservice; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class MicroserviceApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /order-ms/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.1.1 9 | 10 | 11 | com.sc 12 | order-ms 13 | 0.0.1-SNAPSHOT 14 | order-ms 15 | Demo project for Spring Boot 16 | 17 | 17 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-data-jpa 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-web 27 | 28 | 29 | org.projectlombok 30 | lombok 31 | 32 | 33 | 34 | com.h2database 35 | h2 36 | runtime 37 | 38 | 39 | 40 | org.springframework.kafka 41 | spring-kafka 42 | 43 | 44 | org.springframework.boot 45 | spring-boot-starter-test 46 | test 47 | 48 | 49 | 50 | 51 | 52 | 53 | org.springframework.boot 54 | spring-boot-maven-plugin 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /order-ms/src/main/java/com/order/ms/OrderMsApplication.java: -------------------------------------------------------------------------------- 1 | package com.order.ms; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class OrderMsApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(OrderMsApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /order-ms/src/main/java/com/order/ms/controller/OrderController.java: -------------------------------------------------------------------------------- 1 | package com.order.ms.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.kafka.core.KafkaTemplate; 5 | import org.springframework.web.bind.annotation.PostMapping; 6 | import org.springframework.web.bind.annotation.RequestBody; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | import com.order.ms.dto.CustomerOrder; 11 | import com.order.ms.dto.OrderEvent; 12 | import com.order.ms.entity.Order; 13 | import com.order.ms.entity.OrderRepository; 14 | 15 | @RestController 16 | @RequestMapping("/api") 17 | public class OrderController { 18 | 19 | @Autowired 20 | private OrderRepository repository; 21 | 22 | @Autowired 23 | private KafkaTemplate kafkaTemplate; 24 | 25 | @PostMapping("/orders") 26 | public void createOrder(@RequestBody CustomerOrder customerOrder) { 27 | Order order = new Order(); 28 | 29 | try { 30 | order.setAmount(customerOrder.getAmount()); 31 | order.setItem(customerOrder.getItem()); 32 | order.setQuantity(customerOrder.getQuantity()); 33 | order.setStatus("CREATED"); 34 | order = repository.save(order); 35 | 36 | customerOrder.setOrderId(order.getId()); 37 | 38 | OrderEvent event = new OrderEvent(); 39 | event.setOrder(customerOrder); 40 | event.setType("ORDER_CREATED"); 41 | kafkaTemplate.send("new-orders", event); 42 | } catch (Exception e) { 43 | order.setStatus("FAILED"); 44 | repository.save(order); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /order-ms/src/main/java/com/order/ms/dto/CustomerOrder.java: -------------------------------------------------------------------------------- 1 | package com.order.ms.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class CustomerOrder { 9 | private String item; 10 | 11 | private int quantity; 12 | 13 | private double amount; 14 | 15 | private String paymentMode; 16 | 17 | private long orderId; 18 | 19 | private String address; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /order-ms/src/main/java/com/order/ms/dto/OrderEvent.java: -------------------------------------------------------------------------------- 1 | package com.order.ms.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class OrderEvent { 9 | 10 | private String type; 11 | 12 | private CustomerOrder order; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /order-ms/src/main/java/com/order/ms/dto/Payment.java: -------------------------------------------------------------------------------- 1 | package com.order.ms.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class Payment { 9 | 10 | private String mode; 11 | 12 | private Long orderId; 13 | 14 | private double amount; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /order-ms/src/main/java/com/order/ms/entity/Order.java: -------------------------------------------------------------------------------- 1 | package com.order.ms.entity; 2 | 3 | import jakarta.persistence.Column; 4 | import jakarta.persistence.Entity; 5 | import jakarta.persistence.GeneratedValue; 6 | import jakarta.persistence.Id; 7 | import lombok.Getter; 8 | import lombok.Setter; 9 | 10 | @Getter 11 | @Setter 12 | @Entity 13 | public class Order { 14 | 15 | @Id 16 | @GeneratedValue 17 | private long id; 18 | 19 | @Column 20 | private String item; 21 | 22 | @Column 23 | private int quantity; 24 | 25 | @Column 26 | private double amount; 27 | 28 | @Column 29 | private String status; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /order-ms/src/main/java/com/order/ms/entity/OrderRepository.java: -------------------------------------------------------------------------------- 1 | package com.order.ms.entity; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | public interface OrderRepository extends CrudRepository { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /order-ms/src/main/java/com/order/ms/service/ReverseOrder.java: -------------------------------------------------------------------------------- 1 | package com.order.ms.service; 2 | 3 | import java.util.Optional; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.kafka.annotation.KafkaListener; 7 | import org.springframework.stereotype.Component; 8 | 9 | import com.fasterxml.jackson.databind.ObjectMapper; 10 | import com.order.ms.dto.OrderEvent; 11 | import com.order.ms.entity.Order; 12 | import com.order.ms.entity.OrderRepository; 13 | 14 | @Component 15 | public class ReverseOrder { 16 | 17 | @Autowired 18 | private OrderRepository repository; 19 | 20 | @KafkaListener(topics = "reversed-orders", groupId = "orders-group") 21 | public void reverseOrder(String event) { 22 | System.out.println("Inside reverse order for order "+event); 23 | 24 | try { 25 | OrderEvent orderEvent = new ObjectMapper().readValue(event, OrderEvent.class); 26 | 27 | Optional order = repository.findById(orderEvent.getOrder().getOrderId()); 28 | 29 | order.ifPresent(o -> { 30 | o.setStatus("FAILED"); 31 | this.repository.save(o); 32 | }); 33 | } catch (Exception e) { 34 | e.printStackTrace(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /order-ms/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.h2.console.enabled=true 2 | spring.datasource.url=jdbc:h2:mem:ordersdb 3 | spring.kafka.bootstrap-servers=localhost:9092 4 | spring.kafka.consumer.group-id=orders-group 5 | spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer 6 | spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer 7 | -------------------------------------------------------------------------------- /order-ms/src/test/java/com/order/microservice/MicroserviceApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.order.microservice; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class MicroserviceApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /payment-ms/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.boot 8 | spring-boot-starter-parent 9 | 3.1.1 10 | 11 | 12 | com.sc 13 | payment-ms 14 | 0.0.1-SNAPSHOT 15 | payment-ms 16 | Demo project for Spring Boot 17 | 18 | 17 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-data-jpa 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-web 28 | 29 | 30 | org.projectlombok 31 | lombok 32 | 33 | 34 | 35 | com.h2database 36 | h2 37 | runtime 38 | 39 | 40 | org.springframework.kafka 41 | spring-kafka 42 | 43 | 44 | org.springframework.boot 45 | spring-boot-starter-test 46 | test 47 | 48 | 49 | 50 | 51 | 52 | 53 | org.springframework.boot 54 | spring-boot-maven-plugin 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /payment-ms/src/main/java/com/payment/ms/PaymentMsApplication.java: -------------------------------------------------------------------------------- 1 | package com.payment.ms; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class PaymentMsApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(PaymentMsApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /payment-ms/src/main/java/com/payment/ms/controller/PaymentController.java: -------------------------------------------------------------------------------- 1 | package com.payment.ms.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.kafka.annotation.KafkaListener; 5 | import org.springframework.kafka.core.KafkaTemplate; 6 | import org.springframework.stereotype.Controller; 7 | 8 | import com.fasterxml.jackson.core.JsonProcessingException; 9 | import com.fasterxml.jackson.databind.JsonMappingException; 10 | import com.fasterxml.jackson.databind.ObjectMapper; 11 | import com.payment.ms.dto.CustomerOrder; 12 | import com.payment.ms.dto.OrderEvent; 13 | import com.payment.ms.dto.PaymentEvent; 14 | import com.payment.ms.entity.Payment; 15 | import com.payment.ms.entity.PaymentRepository; 16 | 17 | @Controller 18 | public class PaymentController { 19 | 20 | @Autowired 21 | private PaymentRepository repository; 22 | 23 | @Autowired 24 | private KafkaTemplate kafkaTemplate; 25 | 26 | @Autowired 27 | private KafkaTemplate kafkaOrderTemplate; 28 | 29 | @KafkaListener(topics = "new-orders", groupId = "orders-group") 30 | public void processPayment(String event) throws JsonMappingException, JsonProcessingException { 31 | System.out.println("Recieved event for payment " + event); 32 | OrderEvent orderEvent = new ObjectMapper().readValue(event, OrderEvent.class); 33 | 34 | CustomerOrder order = orderEvent.getOrder(); 35 | Payment payment = new Payment(); 36 | 37 | try { 38 | payment.setAmount(order.getAmount()); 39 | payment.setMode(order.getPaymentMode()); 40 | payment.setOrderId(order.getOrderId()); 41 | payment.setStatus("SUCCESS"); 42 | repository.save(payment); 43 | 44 | PaymentEvent paymentEvent = new PaymentEvent(); 45 | paymentEvent.setOrder(orderEvent.getOrder()); 46 | paymentEvent.setType("PAYMENT_CREATED"); 47 | kafkaTemplate.send("new-payments", paymentEvent); 48 | } catch (Exception e) { 49 | payment.setOrderId(order.getOrderId()); 50 | payment.setStatus("FAILED"); 51 | repository.save(payment); 52 | 53 | OrderEvent oe = new OrderEvent(); 54 | oe.setOrder(order); 55 | oe.setType("ORDER_REVERSED"); 56 | kafkaOrderTemplate.send("reversed-orders", orderEvent); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /payment-ms/src/main/java/com/payment/ms/dto/CustomerOrder.java: -------------------------------------------------------------------------------- 1 | package com.payment.ms.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class CustomerOrder { 9 | 10 | private String item; 11 | 12 | private int quantity; 13 | 14 | private double amount; 15 | 16 | private String paymentMode; 17 | 18 | private Long orderId; 19 | 20 | private String address; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /payment-ms/src/main/java/com/payment/ms/dto/OrderEvent.java: -------------------------------------------------------------------------------- 1 | package com.payment.ms.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class OrderEvent { 9 | 10 | private String type; 11 | 12 | private CustomerOrder order; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /payment-ms/src/main/java/com/payment/ms/dto/PaymentEvent.java: -------------------------------------------------------------------------------- 1 | package com.payment.ms.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | @Getter 8 | @Setter 9 | @ToString 10 | public class PaymentEvent { 11 | 12 | private String type; 13 | 14 | private CustomerOrder order; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /payment-ms/src/main/java/com/payment/ms/dto/Stock.java: -------------------------------------------------------------------------------- 1 | package com.payment.ms.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class Stock { 9 | 10 | private String item; 11 | 12 | private int quantity; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /payment-ms/src/main/java/com/payment/ms/entity/Payment.java: -------------------------------------------------------------------------------- 1 | package com.payment.ms.entity; 2 | 3 | import jakarta.persistence.Column; 4 | import jakarta.persistence.Entity; 5 | import jakarta.persistence.GeneratedValue; 6 | import jakarta.persistence.Id; 7 | import lombok.Getter; 8 | import lombok.Setter; 9 | 10 | @Entity 11 | @Getter 12 | @Setter 13 | public class Payment { 14 | 15 | @Id 16 | @GeneratedValue 17 | private Long id; 18 | 19 | @Column 20 | private String mode; 21 | 22 | @Column 23 | private Long orderId; 24 | 25 | @Column 26 | private double amount; 27 | 28 | @Column 29 | private String status; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /payment-ms/src/main/java/com/payment/ms/entity/PaymentRepository.java: -------------------------------------------------------------------------------- 1 | package com.payment.ms.entity; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.repository.CrudRepository; 6 | 7 | public interface PaymentRepository extends CrudRepository { 8 | 9 | public List findByOrderId(long orderId); 10 | } 11 | -------------------------------------------------------------------------------- /payment-ms/src/main/java/com/payment/ms/service/ReversePayment.java: -------------------------------------------------------------------------------- 1 | package com.payment.ms.service; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.kafka.annotation.KafkaListener; 5 | import org.springframework.kafka.core.KafkaTemplate; 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.fasterxml.jackson.databind.ObjectMapper; 9 | import com.payment.ms.dto.CustomerOrder; 10 | import com.payment.ms.dto.OrderEvent; 11 | import com.payment.ms.dto.PaymentEvent; 12 | import com.payment.ms.entity.Payment; 13 | import com.payment.ms.entity.PaymentRepository; 14 | 15 | @Component 16 | public class ReversePayment { 17 | 18 | @Autowired 19 | private PaymentRepository repository; 20 | 21 | @Autowired 22 | private KafkaTemplate kafkaTemplate; 23 | 24 | @KafkaListener(topics = "reversed-payments", groupId = "payments-group") 25 | public void reversePayment(String event) { 26 | System.out.println("Inside reverse payment for order "+event); 27 | 28 | try { 29 | PaymentEvent paymentEvent = new ObjectMapper().readValue(event, PaymentEvent.class); 30 | 31 | CustomerOrder order = paymentEvent.getOrder(); 32 | 33 | Iterable payments = this.repository.findByOrderId(order.getOrderId()); 34 | 35 | payments.forEach(p -> { 36 | p.setStatus("FAILED"); 37 | repository.save(p); 38 | }); 39 | 40 | OrderEvent orderEvent = new OrderEvent(); 41 | orderEvent.setOrder(paymentEvent.getOrder()); 42 | orderEvent.setType("ORDER_REVERSED"); 43 | kafkaTemplate.send("reversed-orders", orderEvent); 44 | } catch (Exception e) { 45 | e.printStackTrace(); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /payment-ms/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=8081 2 | spring.h2.console.enabled=true 3 | spring.datasource.url=jdbc:h2:mem:paymentsdb 4 | spring.kafka.bootstrap-servers=localhost:9092 5 | spring.kafka.consumer.group-id=payments-group 6 | spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer 7 | spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer 8 | 9 | -------------------------------------------------------------------------------- /payment-ms/src/test/java/com/payment/microservice/MicroserviceApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.payment.microservice; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class MicroserviceApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /stock-ms/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.boot 8 | spring-boot-starter-parent 9 | 3.1.1 10 | 11 | 12 | com.sc 13 | stock-ms 14 | 0.0.1-SNAPSHOT 15 | stock-ms 16 | Demo project for Spring Boot 17 | 18 | 17 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-data-jpa 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-web 28 | 29 | 30 | org.projectlombok 31 | lombok 32 | 33 | 34 | 35 | com.h2database 36 | h2 37 | runtime 38 | 39 | 40 | 41 | org.springframework.kafka 42 | spring-kafka 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-starter-test 47 | test 48 | 49 | 50 | 51 | 52 | 53 | 54 | org.springframework.boot 55 | spring-boot-maven-plugin 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /stock-ms/src/main/java/com/stock/ms/StockMsApplication.java: -------------------------------------------------------------------------------- 1 | package com.stock.ms; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class StockMsApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(StockMsApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /stock-ms/src/main/java/com/stock/ms/controller/StockController.java: -------------------------------------------------------------------------------- 1 | package com.stock.ms.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.kafka.annotation.KafkaListener; 5 | import org.springframework.kafka.core.KafkaTemplate; 6 | import org.springframework.web.bind.annotation.PostMapping; 7 | import org.springframework.web.bind.annotation.RequestBody; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | import com.fasterxml.jackson.core.JsonProcessingException; 12 | import com.fasterxml.jackson.databind.JsonMappingException; 13 | import com.fasterxml.jackson.databind.ObjectMapper; 14 | import com.stock.ms.dto.CustomerOrder; 15 | import com.stock.ms.dto.DeliveryEvent; 16 | import com.stock.ms.dto.PaymentEvent; 17 | import com.stock.ms.dto.Stock; 18 | import com.stock.ms.entity.WareHouse; 19 | import com.stock.ms.entity.StockRepository; 20 | 21 | @RestController 22 | @RequestMapping("/api") 23 | public class StockController { 24 | 25 | @Autowired 26 | private StockRepository repository; 27 | 28 | @Autowired 29 | private KafkaTemplate kafkaTemplate; 30 | 31 | @Autowired 32 | private KafkaTemplate kafkaPaymentTemplate; 33 | 34 | @KafkaListener(topics = "new-payments", groupId = "payments-group") 35 | public void updateStock(String paymentEvent) throws JsonMappingException, JsonProcessingException { 36 | System.out.println("Inside update inventory for order "+paymentEvent); 37 | 38 | DeliveryEvent event = new DeliveryEvent(); 39 | 40 | PaymentEvent p = new ObjectMapper().readValue(paymentEvent, PaymentEvent.class); 41 | CustomerOrder order = p.getOrder(); 42 | 43 | try { 44 | Iterable inventories = repository.findByItem(order.getItem()); 45 | 46 | boolean exists = inventories.iterator().hasNext(); 47 | 48 | if (!exists) { 49 | System.out.println("Stock not exist so reverting the order"); 50 | throw new Exception("Stock not available"); 51 | } 52 | 53 | inventories.forEach(i -> { 54 | i.setQuantity(i.getQuantity() - order.getQuantity()); 55 | 56 | repository.save(i); 57 | }); 58 | 59 | event.setType("STOCK_UPDATED"); 60 | event.setOrder(p.getOrder()); 61 | kafkaTemplate.send("new-stock", event); 62 | } catch (Exception e) { 63 | PaymentEvent pe = new PaymentEvent(); 64 | pe.setOrder(order); 65 | pe.setType("PAYMENT_REVERSED"); 66 | kafkaPaymentTemplate.send("reversed-payments", pe); 67 | } 68 | } 69 | 70 | @PostMapping("/addItems") 71 | public void addItems(@RequestBody Stock stock) { 72 | Iterable items = repository.findByItem(stock.getItem()); 73 | 74 | if (items.iterator().hasNext()) { 75 | items.forEach(i -> { 76 | i.setQuantity(stock.getQuantity() + i.getQuantity()); 77 | repository.save(i); 78 | }); 79 | } else { 80 | WareHouse i = new WareHouse(); 81 | i.setItem(stock.getItem()); 82 | i.setQuantity(stock.getQuantity()); 83 | repository.save(i); 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /stock-ms/src/main/java/com/stock/ms/dto/CustomerOrder.java: -------------------------------------------------------------------------------- 1 | package com.stock.ms.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class CustomerOrder { 9 | 10 | private String item; 11 | 12 | private int quantity; 13 | 14 | private double amount; 15 | 16 | private String paymentMode; 17 | 18 | private Long orderId; 19 | 20 | private String address; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /stock-ms/src/main/java/com/stock/ms/dto/DeliveryEvent.java: -------------------------------------------------------------------------------- 1 | package com.stock.ms.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class DeliveryEvent { 9 | 10 | private String type; 11 | 12 | private CustomerOrder order; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /stock-ms/src/main/java/com/stock/ms/dto/PaymentEvent.java: -------------------------------------------------------------------------------- 1 | package com.stock.ms.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class PaymentEvent { 9 | 10 | private String type; 11 | 12 | private CustomerOrder order; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /stock-ms/src/main/java/com/stock/ms/dto/Stock.java: -------------------------------------------------------------------------------- 1 | package com.stock.ms.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class Stock { 9 | 10 | private String item; 11 | 12 | private int quantity; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /stock-ms/src/main/java/com/stock/ms/entity/StockRepository.java: -------------------------------------------------------------------------------- 1 | package com.stock.ms.entity; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | public interface StockRepository extends CrudRepository { 6 | 7 | Iterable findByItem(String item); 8 | } 9 | -------------------------------------------------------------------------------- /stock-ms/src/main/java/com/stock/ms/entity/WareHouse.java: -------------------------------------------------------------------------------- 1 | package com.stock.ms.entity; 2 | 3 | import jakarta.persistence.Column; 4 | import jakarta.persistence.Entity; 5 | import jakarta.persistence.GeneratedValue; 6 | import jakarta.persistence.Id; 7 | import lombok.Getter; 8 | import lombok.Setter; 9 | 10 | @Entity 11 | @Getter 12 | @Setter 13 | public class WareHouse { 14 | 15 | @Id 16 | @GeneratedValue 17 | private long id; 18 | 19 | @Column 20 | private int quantity; 21 | 22 | @Column 23 | private String item; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /stock-ms/src/main/java/com/stock/ms/service/ReversesStock.java: -------------------------------------------------------------------------------- 1 | package com.stock.ms.service; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.kafka.annotation.KafkaListener; 5 | import org.springframework.kafka.core.KafkaTemplate; 6 | 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | import com.fasterxml.jackson.databind.ObjectMapper; 10 | import com.stock.ms.dto.DeliveryEvent; 11 | import com.stock.ms.dto.PaymentEvent; 12 | import com.stock.ms.entity.WareHouse; 13 | import com.stock.ms.entity.StockRepository; 14 | 15 | @RestController 16 | public class ReversesStock { 17 | 18 | @Autowired 19 | private StockRepository repository; 20 | 21 | @Autowired 22 | private KafkaTemplate kafkaTemplate; 23 | 24 | @KafkaListener(topics = "reversed-stock", groupId = "stock-group") 25 | public void reverseStock(String event) { 26 | System.out.println("Inside reverse stock for order "+event); 27 | 28 | try { 29 | DeliveryEvent deliveryEvent = new ObjectMapper().readValue(event, DeliveryEvent.class); 30 | 31 | Iterable inv = this.repository.findByItem(deliveryEvent.getOrder().getItem()); 32 | 33 | inv.forEach(i -> { 34 | i.setQuantity(i.getQuantity() + deliveryEvent.getOrder().getQuantity()); 35 | repository.save(i); 36 | }); 37 | 38 | PaymentEvent paymentEvent = new PaymentEvent(); 39 | paymentEvent.setOrder(deliveryEvent.getOrder()); 40 | paymentEvent.setType("PAYMENT_REVERSED"); 41 | kafkaTemplate.send("reversed-payments", paymentEvent); 42 | } catch (Exception e) { 43 | e.printStackTrace(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /stock-ms/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port = 8082 2 | spring.h2.console.enabled=true 3 | spring.datasource.url=jdbc:h2:mem:stockdb 4 | 5 | spring.kafka.bootstrap-servers=localhost:9092 6 | spring.kafka.consumer.group-id=stock-group 7 | spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer 8 | spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer 9 | 10 | 11 | -------------------------------------------------------------------------------- /stock-ms/src/test/java/com/inventory/microservice/MicroserviceApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.inventory.microservice; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class MicroserviceApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | --------------------------------------------------------------------------------