├── install_dependencies.sh ├── .gitignore ├── CustomerService ├── settings.gradle ├── .gradle │ └── 3.1 │ │ └── taskArtifacts │ │ ├── cache.properties │ │ ├── fileHashes.bin │ │ ├── fileSnapshots.bin │ │ ├── taskArtifacts.bin │ │ └── cache.properties.lock ├── src │ └── main │ │ ├── resources │ │ ├── CustomerDDL.sql │ │ └── application.properties │ │ └── java │ │ └── com │ │ └── eshop │ │ └── user │ │ ├── repository │ │ ├── CustomerRepository.java │ │ └── CustomerOrderRepository.java │ │ ├── rest │ │ ├── CustomerRestService.java │ │ └── impl │ │ │ └── CustomerRestServiceImpl.java │ │ ├── domain │ │ ├── Customer.java │ │ └── CustomerOrders.java │ │ ├── service │ │ ├── CustomerService.java │ │ └── impl │ │ │ └── CustomerServiceImpl.java │ │ ├── listener │ │ └── MessageListener.java │ │ └── config │ │ └── CustomerConfig.java └── build.gradle ├── OrderService ├── settings.gradle ├── src │ └── main │ │ ├── java │ │ └── com │ │ │ └── eshop │ │ │ └── order │ │ │ ├── rest │ │ │ ├── OrderRestService.java │ │ │ └── impl │ │ │ │ └── OrderRestServiceImpl.java │ │ │ ├── repository │ │ │ └── OrderRepository.java │ │ │ ├── service │ │ │ ├── OrderService.java │ │ │ └── impl │ │ │ │ └── OrderServiceImpl.java │ │ │ ├── domain │ │ │ ├── OrderDetails.java │ │ │ └── Order.java │ │ │ ├── listener │ │ │ └── MessageListener.java │ │ │ └── config │ │ │ └── OrderConfig.java │ │ └── resources │ │ ├── OrderDDL.sql │ │ └── application.properties └── build.gradle ├── ShippingService ├── settings.gradle ├── src │ └── main │ │ ├── resources │ │ ├── ShippingDDL.sql │ │ └── application.properties │ │ └── java │ │ └── com │ │ └── eshop │ │ └── shipping │ │ ├── rest │ │ ├── ShippingRestService.java │ │ └── impl │ │ │ └── ShippingRestServiceImpl.java │ │ ├── service │ │ ├── ShippingService.java │ │ └── impl │ │ │ └── ShippingServiceImpl.java │ │ ├── repository │ │ └── ShippingRepository.java │ │ ├── domain │ │ └── Shipping.java │ │ └── config │ │ └── ShippingConfig.java └── build.gradle ├── .travis.yml ├── ProductService ├── settings.gradle ├── src │ └── main │ │ ├── resources │ │ ├── ProductDDL.sql │ │ └── application.properties │ │ └── java │ │ └── com │ │ └── eshop │ │ └── product │ │ ├── repository │ │ └── ProductRepository.java │ │ ├── service │ │ ├── ProductService.java │ │ └── impl │ │ │ └── ProductServiceImpl.java │ │ ├── rest │ │ ├── ProductRestService.java │ │ └── impl │ │ │ └── ProductRestServiceImpl.java │ │ ├── domain │ │ └── Product.java │ │ └── config │ │ └── ProductConfig.java └── build.gradle ├── DiscoveryService ├── src │ └── main │ │ ├── resources │ │ └── application.properties │ │ └── java │ │ └── com │ │ └── eshop │ │ └── discovery │ │ └── config │ │ └── DiscoveryConfig.java └── build.gradle ├── GatewayService ├── src │ └── main │ │ ├── resources │ │ └── application.properties │ │ └── java │ │ └── com │ │ └── eshop │ │ └── gateway │ │ ├── client │ │ ├── ProductClient.java │ │ ├── OrderClient.java │ │ ├── ShippingClient.java │ │ └── CustomerClient.java │ │ ├── rest │ │ ├── GatewayRestService.java │ │ └── impl │ │ │ └── GatewayRestServiceImpl.java │ │ ├── repository │ │ ├── GatewayRepository.java │ │ └── impl │ │ │ └── GatewayRepositoryImpl.java │ │ └── config │ │ └── GatewayConfig.java └── build.gradle ├── CommonService ├── src │ └── main │ │ └── java │ │ └── com │ │ └── eshop │ │ └── common │ │ ├── enums │ │ ├── OrderStatus.java │ │ └── ShippingStatus.java │ │ ├── config │ │ ├── CommonConfig.java │ │ └── KafkaConfig.java │ │ └── beans │ │ ├── ShippingBean.java │ │ ├── CustomerBean.java │ │ ├── ProductBean.java │ │ ├── Event.java │ │ ├── CustomerOrdersBean.java │ │ └── OrderBean.java └── build.gradle ├── settings.gradle ├── README.md └── LICENSE /install_dependencies.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | gradle install 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #IntelliJ 2 | .idea/ 3 | **/*.iml 4 | **/target/ 5 | -------------------------------------------------------------------------------- /CustomerService/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'EShop' 2 | 3 | -------------------------------------------------------------------------------- /OrderService/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'EShop' 2 | 3 | -------------------------------------------------------------------------------- /ShippingService/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'EShop' 2 | 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language : java 2 | install: ./install_dependencies.sh 3 | -------------------------------------------------------------------------------- /CustomerService/.gradle/3.1/taskArtifacts/cache.properties: -------------------------------------------------------------------------------- 1 | #Wed Dec 21 17:52:52 PST 2016 2 | -------------------------------------------------------------------------------- /ProductService/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'EShop' 2 | rootProject.name = 'ProductService' 3 | 4 | -------------------------------------------------------------------------------- /DiscoveryService/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=8761 2 | eureka.client.registerWithEureka=false 3 | eureka.client.fetchRegistry=false -------------------------------------------------------------------------------- /ShippingService/src/main/resources/ShippingDDL.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE SHIPPING 2 | ( 3 | ID INTEGER, 4 | ORDER_ID INTEGER, 5 | STATUS VARCHAR(20), 6 | PRIMARY KEY (ID) 7 | ); 8 | -------------------------------------------------------------------------------- /CustomerService/.gradle/3.1/taskArtifacts/fileHashes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/striderarun/ecommerce-microservices/HEAD/CustomerService/.gradle/3.1/taskArtifacts/fileHashes.bin -------------------------------------------------------------------------------- /CustomerService/.gradle/3.1/taskArtifacts/fileSnapshots.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/striderarun/ecommerce-microservices/HEAD/CustomerService/.gradle/3.1/taskArtifacts/fileSnapshots.bin -------------------------------------------------------------------------------- /CustomerService/.gradle/3.1/taskArtifacts/taskArtifacts.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/striderarun/ecommerce-microservices/HEAD/CustomerService/.gradle/3.1/taskArtifacts/taskArtifacts.bin -------------------------------------------------------------------------------- /GatewayService/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=gatewayService 2 | eureka.client.registerWithEureka=false 3 | 4 | server.port=8080 5 | server.contextPath=/eshop -------------------------------------------------------------------------------- /CustomerService/.gradle/3.1/taskArtifacts/cache.properties.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/striderarun/ecommerce-microservices/HEAD/CustomerService/.gradle/3.1/taskArtifacts/cache.properties.lock -------------------------------------------------------------------------------- /ProductService/src/main/resources/ProductDDL.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE PRODUCT 2 | ( 3 | ID INTEGER, 4 | NAME VARCHAR(20), 5 | PRICE VARCHAR(20), 6 | CATEGORY VARCHAR(20), 7 | PRIMARY KEY (ID) 8 | ); 9 | -------------------------------------------------------------------------------- /CommonService/src/main/java/com/eshop/common/enums/OrderStatus.java: -------------------------------------------------------------------------------- 1 | package com.eshop.common.enums; 2 | 3 | /** 4 | * Created by arun_subramonian on 12/18/16. 5 | */ 6 | public enum OrderStatus { 7 | 8 | PLACED, SHIPPED, DELIVERED 9 | } 10 | -------------------------------------------------------------------------------- /CommonService/src/main/java/com/eshop/common/enums/ShippingStatus.java: -------------------------------------------------------------------------------- 1 | package com.eshop.common.enums; 2 | 3 | /** 4 | * Created by arun_subramonian on 12/18/16. 5 | */ 6 | public enum ShippingStatus { 7 | 8 | SHIPPED, DELIVERED 9 | } 10 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include 'CommonService' 2 | include 'CustomerService' 3 | include 'OrderService' 4 | include 'ShippingService' 5 | include 'ProductService' 6 | include 'GatewayService' 7 | include 'DiscoveryService' 8 | include 'DiscoveryService' 9 | 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/striderarun/microservices-spring-cloud-netflix-oss.svg?branch=master)](https://travis-ci.org/striderarun/microservices-spring-cloud-netflix-oss) 2 | 3 | # Ecommerce microservices 4 | 5 | A Spring project using Spring Cloud Netflix OSS libraries to implement micro services with service discovery 6 | -------------------------------------------------------------------------------- /ShippingService/src/main/java/com/eshop/shipping/rest/ShippingRestService.java: -------------------------------------------------------------------------------- 1 | package com.eshop.shipping.rest; 2 | 3 | /** 4 | * Created by arun_subramonian on 12/19/16. 5 | */ 6 | public interface ShippingRestService { 7 | 8 | void createShipping(Long orderId); 9 | 10 | void acknowledgeDelivery(Long shippingId); 11 | } 12 | -------------------------------------------------------------------------------- /OrderService/src/main/java/com/eshop/order/rest/OrderRestService.java: -------------------------------------------------------------------------------- 1 | package com.eshop.order.rest; 2 | 3 | import com.eshop.common.beans.OrderBean; 4 | import com.eshop.order.domain.Order; 5 | 6 | /** 7 | * Created by arun_subramonian on 12/19/16. 8 | */ 9 | public interface OrderRestService { 10 | 11 | OrderBean createOrder(OrderBean orderBean); 12 | } 13 | -------------------------------------------------------------------------------- /CustomerService/src/main/resources/CustomerDDL.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE CUSTOMER 2 | ( 3 | ID INTEGER, 4 | NAME VARCHAR(20), 5 | EMAIL VARCHAR(20), 6 | PHONE_NO VARCHAR(20), 7 | PRIMARY KEY (ID) 8 | ); 9 | 10 | CREATE TABLE CUSTOMER_ORDERS 11 | ( 12 | ID INTEGER, 13 | CUSTOMER_ID INTEGER, 14 | ORDER_ID INTEGER, 15 | ORDER_STATUS VARCHAR(10), 16 | PRIMARY KEY (ID) 17 | ); 18 | 19 | 20 | -------------------------------------------------------------------------------- /OrderService/src/main/java/com/eshop/order/repository/OrderRepository.java: -------------------------------------------------------------------------------- 1 | package com.eshop.order.repository; 2 | 3 | import com.eshop.order.domain.Order; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | /** 7 | * Created by arun_subramonian on 12/18/16. 8 | */ 9 | public interface OrderRepository extends JpaRepository { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /OrderService/src/main/resources/OrderDDL.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE ORDERS 2 | ( 3 | ID INTEGER, 4 | CUSTOMER_ID INTEGER, 5 | COST INTEGER, 6 | STATUS VARCHAR(20), 7 | PRIMARY KEY (ID) 8 | ); 9 | 10 | CREATE TABLE ORDER_DETAILS 11 | ( 12 | ID INTEGER, 13 | ORDER_ID INTEGER, 14 | PRODUCT_ID INTEGER, 15 | PRIMARY KEY (ID), 16 | FOREIGN KEY (ORDER_ID) REFERENCES ORDERS (ID) 17 | ); 18 | 19 | 20 | -------------------------------------------------------------------------------- /ProductService/src/main/java/com/eshop/product/repository/ProductRepository.java: -------------------------------------------------------------------------------- 1 | package com.eshop.product.repository; 2 | 3 | import com.eshop.product.domain.Product; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | /** 7 | * Created by arun_subramonian on 12/18/16. 8 | */ 9 | public interface ProductRepository extends JpaRepository { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /ShippingService/src/main/java/com/eshop/shipping/service/ShippingService.java: -------------------------------------------------------------------------------- 1 | package com.eshop.shipping.service; 2 | 3 | import com.eshop.shipping.domain.Shipping; 4 | 5 | /** 6 | * Created by arun_subramonian on 12/19/16. 7 | */ 8 | public interface ShippingService { 9 | 10 | void createShippingRequest(Long orderId); 11 | 12 | void acknowledgeDelivery(Long shippingId); 13 | } 14 | -------------------------------------------------------------------------------- /ShippingService/src/main/java/com/eshop/shipping/repository/ShippingRepository.java: -------------------------------------------------------------------------------- 1 | package com.eshop.shipping.repository; 2 | 3 | import com.eshop.shipping.domain.Shipping; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | /** 7 | * Created by arun_subramonian on 12/18/16. 8 | */ 9 | public interface ShippingRepository extends JpaRepository { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /ProductService/src/main/java/com/eshop/product/service/ProductService.java: -------------------------------------------------------------------------------- 1 | package com.eshop.product.service; 2 | 3 | import com.eshop.common.beans.ProductBean; 4 | import com.eshop.product.domain.Product; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Created by arun_subramonian on 12/19/16. 10 | */ 11 | public interface ProductService { 12 | 13 | List fetchAllProducts(); 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /CustomerService/src/main/java/com/eshop/user/repository/CustomerRepository.java: -------------------------------------------------------------------------------- 1 | package com.eshop.user.repository; 2 | 3 | import com.eshop.user.domain.Customer; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Created by arun_subramonian on 12/18/16. 10 | */ 11 | public interface CustomerRepository extends JpaRepository { 12 | 13 | 14 | } 15 | -------------------------------------------------------------------------------- /ProductService/src/main/java/com/eshop/product/rest/ProductRestService.java: -------------------------------------------------------------------------------- 1 | package com.eshop.product.rest; 2 | 3 | import com.eshop.common.beans.ProductBean; 4 | import com.eshop.product.domain.Product; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Created by arun_subramonian on 12/19/16. 10 | */ 11 | public interface ProductRestService { 12 | 13 | /* 14 | * Fetch all products 15 | * 16 | */ 17 | List fetchAllProducts(); 18 | } 19 | -------------------------------------------------------------------------------- /OrderService/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=orderService 2 | eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ 3 | 4 | server.port=0 5 | server.contextPath=/eshop 6 | 7 | #Datasource properties 8 | spring.datasource.driverClassName=org.hsqldb.jdbcDriver 9 | spring.datasource.url=jdbc:hsqldb:hsql://localhost 10 | spring.datasource.username=SA 11 | spring.datasource.password= 12 | 13 | 14 | #JPA Properties 15 | spring.jpa.show-sql=true 16 | spring.jpa.hibernate.ddl-auto=update -------------------------------------------------------------------------------- /OrderService/src/main/java/com/eshop/order/service/OrderService.java: -------------------------------------------------------------------------------- 1 | package com.eshop.order.service; 2 | 3 | import com.eshop.common.beans.OrderBean; 4 | import com.eshop.common.enums.OrderStatus; 5 | import com.eshop.order.domain.Order; 6 | 7 | /** 8 | * Created by arun_subramonian on 12/19/16. 9 | */ 10 | public interface OrderService { 11 | 12 | OrderBean findOrder(Long orderId); 13 | 14 | OrderBean createOrder(OrderBean orderBean); 15 | 16 | void updateOrderStatus(Long orderId, OrderStatus orderStatus); 17 | } 18 | -------------------------------------------------------------------------------- /ProductService/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=productService 2 | 3 | eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ 4 | 5 | server.port=0 6 | server.contextPath=/eshop 7 | 8 | #Datasource properties 9 | spring.datasource.driverClassName=org.hsqldb.jdbcDriver 10 | spring.datasource.url=jdbc:hsqldb:hsql://localhost 11 | spring.datasource.username=SA 12 | spring.datasource.password= 13 | 14 | 15 | #JPA Properties 16 | spring.jpa.show-sql=true 17 | spring.jpa.hibernate.ddl-auto=update -------------------------------------------------------------------------------- /CustomerService/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=customerService 2 | 3 | eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ 4 | 5 | server.port=0 6 | server.contextPath=/eshop 7 | 8 | #Datasource properties 9 | spring.datasource.driverClassName=org.hsqldb.jdbcDriver 10 | spring.datasource.url=jdbc:hsqldb:hsql://localhost 11 | spring.datasource.username=SA 12 | spring.datasource.password= 13 | 14 | 15 | #JPA Properties 16 | spring.jpa.show-sql=true 17 | spring.jpa.hibernate.ddl-auto=update -------------------------------------------------------------------------------- /ShippingService/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=shippingService 2 | 3 | eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ 4 | 5 | server.port=0 6 | server.contextPath=/eshop 7 | 8 | #Datasource properties 9 | spring.datasource.driverClassName=org.hsqldb.jdbcDriver 10 | spring.datasource.url=jdbc:hsqldb:hsql://localhost 11 | spring.datasource.username=SA 12 | spring.datasource.password= 13 | 14 | 15 | #JPA Properties 16 | spring.jpa.show-sql=true 17 | spring.jpa.hibernate.ddl-auto=update -------------------------------------------------------------------------------- /DiscoveryService/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.arun.ecommerce' 2 | version '1.0-SNAPSHOT' 3 | 4 | apply from: '../build.gradle' 5 | 6 | apply plugin: 'java' 7 | apply plugin: 'org.springframework.boot' 8 | 9 | dependencyManagement { 10 | imports { 11 | mavenBom "org.springframework.cloud:spring-cloud-dependencies:Brixton.RELEASE" 12 | } 13 | } 14 | 15 | repositories { 16 | mavenCentral() 17 | } 18 | 19 | dependencies { 20 | compile('org.springframework.cloud:spring-cloud-starter-eureka-server:1.2.3.RELEASE') 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /CommonService/src/main/java/com/eshop/common/config/CommonConfig.java: -------------------------------------------------------------------------------- 1 | package com.eshop.common.config; 2 | 3 | import org.dozer.DozerBeanMapper; 4 | import org.dozer.Mapper; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | /** 9 | * Created by arun_subramonian on 12/21/16. 10 | */ 11 | @Configuration 12 | public class CommonConfig { 13 | 14 | @Bean 15 | public Mapper mapper() { 16 | Mapper mapper = new DozerBeanMapper(); 17 | return mapper; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /CommonService/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.arun.ecommerce' 2 | version '1.0-SNAPSHOT' 3 | 4 | apply plugin: 'java' 5 | apply plugin: 'maven' 6 | 7 | 8 | repositories { 9 | mavenLocal() 10 | mavenCentral() 11 | } 12 | 13 | dependencies { 14 | compile("org.springframework.kafka:spring-kafka:1.1.1.RELEASE") 15 | compile("org.springframework:spring-core:4.2.4.RELEASE") 16 | compile("org.springframework:spring-beans:4.2.4.RELEASE") 17 | compile("org.springframework:spring-context:4.2.4.RELEASE") 18 | compile("net.sf.dozer:dozer:5.5.1") 19 | 20 | } 21 | -------------------------------------------------------------------------------- /GatewayService/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.arun.ecommerce' 2 | version '1.0-SNAPSHOT' 3 | 4 | apply from : '../build.gradle' 5 | 6 | apply plugin: 'java' 7 | apply plugin: 'org.springframework.boot' 8 | 9 | repositories { 10 | mavenLocal() 11 | mavenCentral() 12 | } 13 | 14 | dependencies { 15 | compile("com.arun.ecommerce:CommonService:1.0-SNAPSHOT") 16 | compile("org.springframework.boot:spring-boot-starter-web") 17 | compile("org.springframework.cloud:spring-cloud-starter-eureka:1.2.3.RELEASE") 18 | compile("org.springframework.cloud:spring-cloud-starter-feign:1.2.3.RELEASE") 19 | } 20 | 21 | -------------------------------------------------------------------------------- /ProductService/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.arun.ecommerce' 2 | version '1.0-SNAPSHOT' 3 | 4 | apply from: '../build.gradle' 5 | 6 | apply plugin: 'java' 7 | apply plugin: 'org.springframework.boot' 8 | 9 | repositories { 10 | mavenLocal() 11 | mavenCentral() 12 | } 13 | 14 | dependencies { 15 | compile("com.arun.ecommerce:CommonService:1.0-SNAPSHOT") 16 | compile("org.springframework.boot:spring-boot-starter-web") 17 | compile("org.springframework.boot:spring-boot-starter-data-jpa") 18 | compile("org.springframework.cloud:spring-cloud-starter-eureka:1.2.3.RELEASE") 19 | compile("org.hsqldb:hsqldb") 20 | } 21 | -------------------------------------------------------------------------------- /ShippingService/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.arun.ecommerce' 2 | version '1.0-SNAPSHOT' 3 | 4 | apply from : '../build.gradle' 5 | 6 | apply plugin: 'java' 7 | apply plugin: 'org.springframework.boot' 8 | 9 | repositories { 10 | mavenLocal() 11 | mavenCentral() 12 | } 13 | 14 | dependencies { 15 | compile("com.arun.ecommerce:CommonService:1.0-SNAPSHOT") 16 | compile("org.springframework.boot:spring-boot-starter-web") 17 | compile("org.springframework.boot:spring-boot-starter-data-jpa") 18 | compile("org.springframework.cloud:spring-cloud-starter-eureka:1.2.3.RELEASE") 19 | compile("org.hsqldb:hsqldb") 20 | } 21 | 22 | -------------------------------------------------------------------------------- /GatewayService/src/main/java/com/eshop/gateway/client/ProductClient.java: -------------------------------------------------------------------------------- 1 | package com.eshop.gateway.client; 2 | 3 | import com.eshop.common.beans.ProductBean; 4 | import org.springframework.cloud.netflix.feign.FeignClient; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RequestMethod; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Created by arun_subramonian on 12/24/16. 12 | */ 13 | @FeignClient("http://productService") 14 | public interface ProductClient { 15 | 16 | @RequestMapping(value = "/eshop/services/product", method = RequestMethod.GET) 17 | List fetchAllProducts(); 18 | } 19 | -------------------------------------------------------------------------------- /CustomerService/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.arun.ecommerce' 2 | version '1.0-SNAPSHOT' 3 | 4 | apply from : '../build.gradle' 5 | 6 | apply plugin: 'java' 7 | apply plugin: 'org.springframework.boot' 8 | 9 | repositories { 10 | mavenLocal() 11 | mavenCentral() 12 | } 13 | 14 | dependencies { 15 | compile("com.arun.ecommerce:CommonService:1.0-SNAPSHOT") 16 | compile("org.springframework.boot:spring-boot-starter-web") 17 | compile("org.springframework.boot:spring-boot-starter-data-jpa") 18 | compile("org.springframework.cloud:spring-cloud-starter-eureka:1.2.3.RELEASE") 19 | compile("org.hsqldb:hsqldb") 20 | compile('org.jsondoc:jsondoc-core:1.2.17') 21 | 22 | } 23 | -------------------------------------------------------------------------------- /CustomerService/src/main/java/com/eshop/user/rest/CustomerRestService.java: -------------------------------------------------------------------------------- 1 | package com.eshop.user.rest; 2 | 3 | import com.eshop.common.beans.CustomerBean; 4 | import com.eshop.common.beans.CustomerOrdersBean; 5 | 6 | import java.util.List; 7 | 8 | 9 | public interface CustomerRestService { 10 | 11 | /** 12 | * Fetch Customer Details 13 | * 14 | */ 15 | CustomerBean fetchCustomerDetails(Long id); 16 | 17 | /** 18 | * Fetch customer orders 19 | * 20 | */ 21 | List fetchCustomerOrders(Long id); 22 | 23 | /* 24 | * Add customer 25 | * 26 | */ 27 | CustomerBean addCustomer(CustomerBean customer); 28 | } 29 | -------------------------------------------------------------------------------- /OrderService/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.arun.ecommerce' 2 | version '1.0-SNAPSHOT' 3 | 4 | apply from : '../build.gradle' 5 | 6 | apply plugin: 'java' 7 | apply plugin: 'org.springframework.boot' 8 | 9 | repositories { 10 | mavenLocal() 11 | mavenCentral() 12 | } 13 | 14 | dependencies { 15 | compile("com.arun.ecommerce:CommonService:1.0-SNAPSHOT") 16 | compile("org.springframework.boot:spring-boot-starter-web") 17 | compile("org.springframework.boot:spring-boot-starter-data-jpa:1.3.1.RELEASE") 18 | compile("org.springframework.cloud:spring-cloud-starter-eureka:1.2.3.RELEASE") 19 | compile("org.hsqldb:hsqldb:2.2.8") 20 | compile('org.jsondoc:jsondoc-core:1.2.17') 21 | } 22 | 23 | -------------------------------------------------------------------------------- /DiscoveryService/src/main/java/com/eshop/discovery/config/DiscoveryConfig.java: -------------------------------------------------------------------------------- 1 | package com.eshop.discovery.config; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 7 | 8 | /** 9 | * Created by arun_subramonian on 12/24/16. 10 | */ 11 | @EnableAutoConfiguration 12 | @SpringBootApplication 13 | @EnableEurekaServer 14 | public class DiscoveryConfig { 15 | 16 | public static void main(String[] args) { 17 | SpringApplication.run(DiscoveryConfig.class, args); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /CustomerService/src/main/java/com/eshop/user/repository/CustomerOrderRepository.java: -------------------------------------------------------------------------------- 1 | package com.eshop.user.repository; 2 | import com.eshop.common.enums.OrderStatus; 3 | import com.eshop.user.domain.CustomerOrders; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Created by arun_subramonian on 12/18/16. 10 | */ 11 | public interface CustomerOrderRepository extends JpaRepository { 12 | 13 | List findByCustomerId(Long customerId); 14 | 15 | CustomerOrders findByCustomerIdAndOrderId(Long customerId, Long orderId); 16 | 17 | CustomerOrders findByOrderId(Long orderId); 18 | 19 | List findByOrderStatus(OrderStatus orderStatus); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /GatewayService/src/main/java/com/eshop/gateway/rest/GatewayRestService.java: -------------------------------------------------------------------------------- 1 | package com.eshop.gateway.rest; 2 | 3 | import com.eshop.common.beans.CustomerBean; 4 | import com.eshop.common.beans.CustomerOrdersBean; 5 | import com.eshop.common.beans.OrderBean; 6 | import com.eshop.common.beans.ProductBean; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Created by arun_subramonian on 12/23/16. 12 | */ 13 | public interface GatewayRestService { 14 | 15 | CustomerBean fetchCustomerDetails(Long id); 16 | 17 | List fetchCustomerOrders(Long id); 18 | 19 | CustomerBean addCustomer(CustomerBean customer); 20 | 21 | List fetchAllProducts(); 22 | 23 | OrderBean createOrder(OrderBean orderBean); 24 | 25 | void createShipping(Long id); 26 | 27 | void acknowledgeDelivery(Long shippingId); 28 | 29 | 30 | } 31 | -------------------------------------------------------------------------------- /CommonService/src/main/java/com/eshop/common/beans/ShippingBean.java: -------------------------------------------------------------------------------- 1 | package com.eshop.common.beans; 2 | 3 | import com.eshop.common.enums.ShippingStatus; 4 | 5 | /** 6 | * Created by arun_subramonian on 12/23/16. 7 | */ 8 | public class ShippingBean { 9 | 10 | private Long id; 11 | private Long orderId; 12 | private ShippingStatus status; 13 | 14 | public Long getId() { 15 | return id; 16 | } 17 | 18 | public void setId(Long id) { 19 | this.id = id; 20 | } 21 | 22 | public Long getOrderId() { 23 | return orderId; 24 | } 25 | 26 | public void setOrderId(Long orderId) { 27 | this.orderId = orderId; 28 | } 29 | 30 | public ShippingStatus getStatus() { 31 | return status; 32 | } 33 | 34 | public void setStatus(ShippingStatus status) { 35 | this.status = status; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /GatewayService/src/main/java/com/eshop/gateway/client/OrderClient.java: -------------------------------------------------------------------------------- 1 | package com.eshop.gateway.client; 2 | 3 | import com.eshop.common.beans.OrderBean; 4 | import com.eshop.common.beans.ProductBean; 5 | import org.springframework.cloud.netflix.feign.FeignClient; 6 | import org.springframework.http.HttpStatus; 7 | import org.springframework.web.bind.annotation.RequestBody; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | import org.springframework.web.bind.annotation.ResponseStatus; 11 | 12 | import java.util.List; 13 | 14 | /** 15 | * Created by arun_subramonian on 12/24/16. 16 | */ 17 | @FeignClient("http://orderService") 18 | public interface OrderClient { 19 | 20 | @RequestMapping(value = "/eshop/services/order", method = RequestMethod.POST) 21 | public OrderBean createOrder(@RequestBody OrderBean orderBean); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /CommonService/src/main/java/com/eshop/common/beans/CustomerBean.java: -------------------------------------------------------------------------------- 1 | package com.eshop.common.beans; 2 | 3 | 4 | public class CustomerBean { 5 | 6 | private Long id; 7 | private String name; 8 | private String email; 9 | private String phoneNo; 10 | 11 | public Long getId() { 12 | return id; 13 | } 14 | 15 | public void setId(Long id) { 16 | this.id = id; 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | 23 | public void setName(String name) { 24 | this.name = name; 25 | } 26 | 27 | public String getEmail() { 28 | return email; 29 | } 30 | 31 | public void setEmail(String email) { 32 | this.email = email; 33 | } 34 | 35 | public String getPhoneNo() { 36 | return phoneNo; 37 | } 38 | 39 | public void setPhoneNo(String phoneNo) { 40 | this.phoneNo = phoneNo; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /GatewayService/src/main/java/com/eshop/gateway/repository/GatewayRepository.java: -------------------------------------------------------------------------------- 1 | package com.eshop.gateway.repository; 2 | 3 | import com.eshop.common.beans.CustomerBean; 4 | import com.eshop.common.beans.CustomerOrdersBean; 5 | import com.eshop.common.beans.OrderBean; 6 | import com.eshop.common.beans.ProductBean; 7 | import org.springframework.web.bind.annotation.PathVariable; 8 | import org.springframework.web.bind.annotation.RequestBody; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * Created by arun_subramonian on 12/23/16. 14 | */ 15 | public interface GatewayRepository { 16 | 17 | CustomerBean fetchCustomerDetails(Long id); 18 | 19 | List fetchCustomerOrders(Long id); 20 | 21 | CustomerBean addCustomer(CustomerBean customer); 22 | 23 | List fetchAllProducts(); 24 | 25 | OrderBean createOrder(OrderBean orderBean); 26 | 27 | void createShipping(Long id); 28 | 29 | void acknowledgeDelivery(Long shippingId); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /GatewayService/src/main/java/com/eshop/gateway/client/ShippingClient.java: -------------------------------------------------------------------------------- 1 | package com.eshop.gateway.client; 2 | 3 | import com.eshop.common.beans.ProductBean; 4 | import org.springframework.cloud.netflix.feign.FeignClient; 5 | import org.springframework.http.HttpStatus; 6 | import org.springframework.web.bind.annotation.PathVariable; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RequestMethod; 9 | import org.springframework.web.bind.annotation.ResponseStatus; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * Created by arun_subramonian on 12/24/16. 15 | */ 16 | @FeignClient("http://shippingService") 17 | public interface ShippingClient { 18 | 19 | @RequestMapping(value = "/eshop/services/shipping/order/{id}", method = RequestMethod.POST) 20 | void createShipping(@PathVariable("id") Long id); 21 | 22 | @RequestMapping(value= "/eshop/services/shipping/{id}", method = RequestMethod.POST) 23 | public void acknowledgeDelivery(@PathVariable("id") Long id); 24 | } 25 | -------------------------------------------------------------------------------- /ProductService/src/main/java/com/eshop/product/service/impl/ProductServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.eshop.product.service.impl; 2 | 3 | import com.eshop.common.beans.ProductBean; 4 | import com.eshop.product.domain.Product; 5 | import com.eshop.product.repository.ProductRepository; 6 | import com.eshop.product.service.ProductService; 7 | import org.dozer.Mapper; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Service; 10 | 11 | import javax.annotation.Resource; 12 | import java.util.List; 13 | import java.util.stream.Collectors; 14 | 15 | /** 16 | * Created by arun_subramonian on 12/19/16. 17 | */ 18 | @Service 19 | public class ProductServiceImpl implements ProductService { 20 | 21 | @Resource 22 | private ProductRepository productRepository; 23 | 24 | @Autowired 25 | private Mapper mapper; 26 | 27 | @Override 28 | public List fetchAllProducts() { 29 | return productRepository.findAll().stream().map(s -> mapper.map(s, ProductBean.class)).collect(Collectors.toList()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /CommonService/src/main/java/com/eshop/common/beans/ProductBean.java: -------------------------------------------------------------------------------- 1 | package com.eshop.common.beans; 2 | 3 | import com.eshop.common.enums.OrderStatus; 4 | 5 | import java.util.Set; 6 | 7 | /** 8 | * Created by arun_subramonian on 12/23/16. 9 | */ 10 | public class ProductBean { 11 | 12 | private Long id; 13 | private String name; 14 | private String price; 15 | private String category; 16 | 17 | 18 | public Long getId() { 19 | return id; 20 | } 21 | 22 | public void setId(Long id) { 23 | this.id = id; 24 | } 25 | 26 | public String getName() { 27 | return name; 28 | } 29 | 30 | public void setName(String name) { 31 | this.name = name; 32 | } 33 | 34 | public String getPrice() { 35 | return price; 36 | } 37 | 38 | public void setPrice(String price) { 39 | this.price = price; 40 | } 41 | 42 | public String getCategory() { 43 | return category; 44 | } 45 | 46 | public void setCategory(String category) { 47 | this.category = category; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /OrderService/src/main/java/com/eshop/order/domain/OrderDetails.java: -------------------------------------------------------------------------------- 1 | package com.eshop.order.domain; 2 | 3 | import javax.persistence.*; 4 | 5 | @Entity 6 | @Table(name="ORDER_DETAILS") 7 | @SequenceGenerator(name = "ORDER_DETAILS_SEQ", sequenceName = "ORDER_DETAILS_SEQ", allocationSize = 1) 8 | public class OrderDetails { 9 | 10 | @Id 11 | @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ORDER_DETAILS_SEQ") 12 | private Long id; 13 | 14 | private Long productId; 15 | 16 | @ManyToOne 17 | @JoinColumn(name = "ORDER_ID") 18 | private Order order; 19 | 20 | public Long getId() { 21 | return id; 22 | } 23 | 24 | public void setId(Long id) { 25 | this.id = id; 26 | } 27 | 28 | public Long getProductId() { 29 | return productId; 30 | } 31 | 32 | public void setProductId(Long productId) { 33 | this.productId = productId; 34 | } 35 | 36 | public Order getOrder() { 37 | return order; 38 | } 39 | 40 | public void setOrder(Order order) { 41 | this.order = order; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ShippingService/src/main/java/com/eshop/shipping/domain/Shipping.java: -------------------------------------------------------------------------------- 1 | package com.eshop.shipping.domain; 2 | 3 | 4 | import com.eshop.common.enums.ShippingStatus; 5 | 6 | import javax.persistence.*; 7 | 8 | @Entity 9 | @Table(name="SHIPPING") 10 | @SequenceGenerator(name = "SHIPPING_SEQ", sequenceName = "SHIPPING_SEQ", allocationSize = 1) 11 | public class Shipping { 12 | 13 | @Id 14 | @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SHIPPING_SEQ") 15 | private Long id; 16 | 17 | private Long orderId; 18 | 19 | @Enumerated(EnumType.STRING) 20 | private ShippingStatus status; 21 | 22 | public Long getId() { 23 | return id; 24 | } 25 | 26 | public void setId(Long id) { 27 | this.id = id; 28 | } 29 | 30 | public Long getOrderId() { 31 | return orderId; 32 | } 33 | 34 | public void setOrderId(Long orderId) { 35 | this.orderId = orderId; 36 | } 37 | 38 | public ShippingStatus getStatus() { 39 | return status; 40 | } 41 | 42 | public void setStatus(ShippingStatus status) { 43 | this.status = status; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /CommonService/src/main/java/com/eshop/common/beans/Event.java: -------------------------------------------------------------------------------- 1 | package com.eshop.common.beans; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Created by arun_subramonian on 12/21/16. 7 | */ 8 | public class Event implements Serializable { 9 | 10 | private Long orderId; 11 | private Long customerId; 12 | private Long productId; 13 | private Long shippingId; 14 | 15 | public Long getOrderId() { 16 | return orderId; 17 | } 18 | 19 | public void setOrderId(Long orderId) { 20 | this.orderId = orderId; 21 | } 22 | 23 | public Long getCustomerId() { 24 | return customerId; 25 | } 26 | 27 | public void setCustomerId(Long customerId) { 28 | this.customerId = customerId; 29 | } 30 | 31 | public Long getProductId() { 32 | return productId; 33 | } 34 | 35 | public void setProductId(Long productId) { 36 | this.productId = productId; 37 | } 38 | 39 | public Long getShippingId() { 40 | return shippingId; 41 | } 42 | 43 | public void setShippingId(Long shippingId) { 44 | this.shippingId = shippingId; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Arun Mohan Subramonian 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /CustomerService/src/main/java/com/eshop/user/domain/Customer.java: -------------------------------------------------------------------------------- 1 | package com.eshop.user.domain; 2 | 3 | import javax.persistence.*; 4 | 5 | @Entity 6 | @Table(name="CUSTOMER") 7 | @SequenceGenerator(name = "CUSTOMER_SEQ", sequenceName = "CUSTOMER_SEQ", allocationSize = 1) 8 | public class Customer { 9 | 10 | @Id 11 | @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CUSTOMER_SEQ") 12 | private Long id; 13 | 14 | private String name; 15 | private String email; 16 | private String phoneNo; 17 | 18 | public Long getId() { 19 | return id; 20 | } 21 | 22 | public void setId(Long id) { 23 | this.id = id; 24 | } 25 | 26 | public String getName() { 27 | return name; 28 | } 29 | 30 | public void setName(String name) { 31 | this.name = name; 32 | } 33 | 34 | public String getEmail() { 35 | return email; 36 | } 37 | 38 | public void setEmail(String email) { 39 | this.email = email; 40 | } 41 | 42 | public String getPhoneNo() { 43 | return phoneNo; 44 | } 45 | 46 | public void setPhoneNo(String phoneNo) { 47 | this.phoneNo = phoneNo; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /CommonService/src/main/java/com/eshop/common/beans/CustomerOrdersBean.java: -------------------------------------------------------------------------------- 1 | package com.eshop.common.beans; 2 | 3 | import com.eshop.common.enums.OrderStatus; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * Created by arun_subramonian on 12/24/16. 9 | */ 10 | public class CustomerOrdersBean implements Serializable { 11 | 12 | private Long id; 13 | private Long customerId; 14 | private Long orderId; 15 | private OrderStatus orderStatus; 16 | 17 | public Long getId() { 18 | return id; 19 | } 20 | 21 | public void setId(Long id) { 22 | this.id = id; 23 | } 24 | 25 | public Long getCustomerId() { 26 | return customerId; 27 | } 28 | 29 | public void setCustomerId(Long customerId) { 30 | this.customerId = customerId; 31 | } 32 | 33 | public Long getOrderId() { 34 | return orderId; 35 | } 36 | 37 | public void setOrderId(Long orderId) { 38 | this.orderId = orderId; 39 | } 40 | 41 | public OrderStatus getOrderStatus() { 42 | return orderStatus; 43 | } 44 | 45 | public void setOrderStatus(OrderStatus orderStatus) { 46 | this.orderStatus = orderStatus; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ProductService/src/main/java/com/eshop/product/domain/Product.java: -------------------------------------------------------------------------------- 1 | package com.eshop.product.domain; 2 | 3 | import javax.persistence.*; 4 | 5 | @Entity 6 | @Table(name="PRODUCT") 7 | @SequenceGenerator(name = "PRODUCT_SEQ", sequenceName = "PRODUCT_SEQ", allocationSize = 1) 8 | public class Product { 9 | 10 | @Id 11 | @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "PRODUCT_SEQ") 12 | private Long id; 13 | 14 | private String name; 15 | private String price; 16 | private String category; 17 | 18 | public Long getId() { 19 | return id; 20 | } 21 | 22 | public void setId(Long id) { 23 | this.id = id; 24 | } 25 | 26 | public String getPrice() { 27 | return price; 28 | } 29 | 30 | public void setPrice(String price) { 31 | this.price = price; 32 | } 33 | 34 | public String getCategory() { 35 | return category; 36 | } 37 | 38 | public void setCategory(String category) { 39 | this.category = category; 40 | } 41 | 42 | public String getName() { 43 | return name; 44 | } 45 | 46 | public void setName(String name) { 47 | this.name = name; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ShippingService/src/main/java/com/eshop/shipping/rest/impl/ShippingRestServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.eshop.shipping.rest.impl; 2 | 3 | import com.eshop.shipping.rest.ShippingRestService; 4 | import com.eshop.shipping.service.ShippingService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.HttpStatus; 7 | import org.springframework.web.bind.annotation.*; 8 | 9 | /** 10 | * Created by arun_subramonian on 12/19/16. 11 | */ 12 | @RestController 13 | @RequestMapping(value = "/services/shipping") 14 | public class ShippingRestServiceImpl implements ShippingRestService { 15 | 16 | @Autowired 17 | private ShippingService shippingService; 18 | 19 | @Override 20 | @RequestMapping(value= "/order/{id}", method = RequestMethod.POST) 21 | @ResponseStatus(HttpStatus.OK) 22 | public void createShipping(@PathVariable Long id) { 23 | shippingService.createShippingRequest(id); 24 | } 25 | 26 | @Override 27 | @RequestMapping(value= "/{id}", method = RequestMethod.POST) 28 | @ResponseStatus(HttpStatus.OK) 29 | public void acknowledgeDelivery(@PathVariable Long shippingId) { 30 | shippingService.acknowledgeDelivery(shippingId); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /GatewayService/src/main/java/com/eshop/gateway/client/CustomerClient.java: -------------------------------------------------------------------------------- 1 | package com.eshop.gateway.client; 2 | 3 | import com.eshop.common.beans.CustomerBean; 4 | import com.eshop.common.beans.CustomerOrdersBean; 5 | import org.springframework.cloud.netflix.feign.FeignClient; 6 | import org.springframework.web.bind.annotation.PathVariable; 7 | import org.springframework.web.bind.annotation.RequestBody; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * Created by arun_subramonian on 12/24/16. 15 | */ 16 | @FeignClient("http://customerService") 17 | public interface CustomerClient { 18 | 19 | @RequestMapping(value = "/eshop/services/customer/{id}", method = RequestMethod.GET) 20 | CustomerBean fetchCustomerDetails(@PathVariable("id") Long id); 21 | 22 | @RequestMapping(value= "/eshop/services/customer/{id}/orders", method = RequestMethod.GET) 23 | List fetchCustomerOrders(@PathVariable("id") Long id); 24 | 25 | @RequestMapping(value = "/eshop/services/customer", method = RequestMethod.POST) 26 | CustomerBean addCustomer(@RequestBody CustomerBean customer); 27 | } 28 | -------------------------------------------------------------------------------- /ProductService/src/main/java/com/eshop/product/rest/impl/ProductRestServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.eshop.product.rest.impl; 2 | 3 | import com.eshop.common.beans.ProductBean; 4 | import com.eshop.product.domain.Product; 5 | import com.eshop.product.rest.ProductRestService; 6 | import com.eshop.product.service.ProductService; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.http.HttpStatus; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestMethod; 11 | import org.springframework.web.bind.annotation.ResponseStatus; 12 | import org.springframework.web.bind.annotation.RestController; 13 | 14 | import java.util.List; 15 | 16 | /** 17 | * Created by arun_subramonian on 12/19/16. 18 | */ 19 | @RestController 20 | @RequestMapping(value = "/services/product") 21 | public class ProductRestServiceImpl implements ProductRestService { 22 | 23 | @Autowired 24 | private ProductService productService; 25 | 26 | @Override 27 | @RequestMapping(method = RequestMethod.GET) 28 | @ResponseStatus(HttpStatus.OK) 29 | public List fetchAllProducts() { 30 | return productService.fetchAllProducts(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /OrderService/src/main/java/com/eshop/order/listener/MessageListener.java: -------------------------------------------------------------------------------- 1 | package com.eshop.order.listener; 2 | 3 | import com.eshop.common.beans.Event; 4 | import com.eshop.common.beans.OrderBean; 5 | import com.eshop.common.enums.OrderStatus; 6 | import com.eshop.order.domain.Order; 7 | import com.eshop.order.service.OrderService; 8 | import com.fasterxml.jackson.databind.ObjectMapper; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.kafka.annotation.KafkaListener; 11 | import org.springframework.stereotype.Component; 12 | 13 | import javax.annotation.Resource; 14 | import java.io.IOException; 15 | 16 | /** 17 | * Created by arun_subramonian on 12/21/16. 18 | */ 19 | @Component 20 | public class MessageListener { 21 | 22 | @Autowired 23 | private ObjectMapper objectMapper; 24 | 25 | @Autowired 26 | private OrderService orderService; 27 | 28 | @KafkaListener(topics = "ORDER_SHIPPED") 29 | public void orderShippedListener(String message) { 30 | try { 31 | Event event = objectMapper.readValue(message, Event.class); 32 | orderService.updateOrderStatus(event.getOrderId(), OrderStatus.SHIPPED); 33 | } catch (IOException e) { 34 | e.printStackTrace(); 35 | } 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /CommonService/src/main/java/com/eshop/common/beans/OrderBean.java: -------------------------------------------------------------------------------- 1 | package com.eshop.common.beans; 2 | 3 | import com.eshop.common.enums.OrderStatus; 4 | 5 | import java.util.Set; 6 | 7 | /** 8 | * Created by arun_subramonian on 12/23/16. 9 | */ 10 | public class OrderBean { 11 | 12 | private Long id; 13 | private Long customerId; 14 | private OrderStatus status; 15 | private Double cost; 16 | private Set productIds; 17 | 18 | public Long getId() { 19 | return id; 20 | } 21 | 22 | public void setId(Long id) { 23 | this.id = id; 24 | } 25 | 26 | public Long getCustomerId() { 27 | return customerId; 28 | } 29 | 30 | public void setCustomerId(Long customerId) { 31 | this.customerId = customerId; 32 | } 33 | 34 | public OrderStatus getStatus() { 35 | return status; 36 | } 37 | 38 | public void setStatus(OrderStatus status) { 39 | this.status = status; 40 | } 41 | 42 | public Double getCost() { 43 | return cost; 44 | } 45 | 46 | public void setCost(Double cost) { 47 | this.cost = cost; 48 | } 49 | 50 | public Set getProductIds() { 51 | return productIds; 52 | } 53 | 54 | public void setProductIds(Set productIds) { 55 | this.productIds = productIds; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /CustomerService/src/main/java/com/eshop/user/domain/CustomerOrders.java: -------------------------------------------------------------------------------- 1 | package com.eshop.user.domain; 2 | 3 | import com.eshop.common.enums.OrderStatus; 4 | 5 | import javax.persistence.*; 6 | 7 | @Entity 8 | @Table(name="CUSTOMER_ORDERS") 9 | @SequenceGenerator(name = "CUSTOMER_ORDERS_SEQ", sequenceName = "CUSTOMER_ORDERS_SEQ", allocationSize = 1) 10 | public class CustomerOrders { 11 | 12 | @Id 13 | @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CUSTOMER_ORDERS_SEQ") 14 | private Long id; 15 | 16 | private Long customerId; 17 | private Long orderId; 18 | 19 | @Enumerated(EnumType.STRING) 20 | private OrderStatus orderStatus; 21 | 22 | public Long getId() { 23 | return id; 24 | } 25 | 26 | public void setId(Long id) { 27 | this.id = id; 28 | } 29 | 30 | public Long getCustomerId() { 31 | return customerId; 32 | } 33 | 34 | public void setCustomerId(Long customerId) { 35 | this.customerId = customerId; 36 | } 37 | 38 | public Long getOrderId() { 39 | return orderId; 40 | } 41 | 42 | public void setOrderId(Long orderId) { 43 | this.orderId = orderId; 44 | } 45 | 46 | public OrderStatus getOrderStatus() { 47 | return orderStatus; 48 | } 49 | 50 | public void setOrderStatus(OrderStatus orderStatus) { 51 | this.orderStatus = orderStatus; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /OrderService/src/main/java/com/eshop/order/rest/impl/OrderRestServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.eshop.order.rest.impl; 2 | 3 | import com.eshop.common.beans.OrderBean; 4 | import com.eshop.order.domain.Order; 5 | import com.eshop.order.rest.OrderRestService; 6 | import com.eshop.order.service.OrderService; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.http.HttpStatus; 9 | import org.springframework.web.bind.annotation.*; 10 | import org.jsondoc.core.annotation.ApiHeader; 11 | import org.jsondoc.core.annotation.ApiHeaders; 12 | import org.jsondoc.core.annotation.ApiMethod; 13 | import org.jsondoc.core.annotation.ApiResponseObject; 14 | 15 | import static org.springframework.http.HttpHeaders.ACCEPT; 16 | import static org.springframework.http.HttpHeaders.CONTENT_TYPE; 17 | 18 | @RestController 19 | @RequestMapping(value = "/services/order") 20 | public class OrderRestServiceImpl implements OrderRestService { 21 | 22 | @Autowired 23 | private OrderService orderService; 24 | 25 | @Override 26 | @RequestMapping(method = RequestMethod.POST) 27 | @ApiMethod(description = "Fetch Customer Orders", responsestatuscode = "200 - OK") 28 | @ApiHeaders(headers = { 29 | @ApiHeader(name = ACCEPT), 30 | @ApiHeader(name = CONTENT_TYPE) 31 | }) 32 | @ResponseStatus(HttpStatus.OK) 33 | public OrderBean createOrder(@RequestBody OrderBean orderBean) { 34 | return orderService.createOrder(orderBean); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /CustomerService/src/main/java/com/eshop/user/service/CustomerService.java: -------------------------------------------------------------------------------- 1 | package com.eshop.user.service; 2 | 3 | import com.eshop.common.beans.CustomerBean; 4 | import com.eshop.common.beans.CustomerOrdersBean; 5 | import com.eshop.common.enums.OrderStatus; 6 | import com.eshop.user.domain.Customer; 7 | import com.eshop.user.domain.CustomerOrders; 8 | 9 | import java.util.List; 10 | 11 | public interface CustomerService { 12 | 13 | /** 14 | * Fetch Customer Details By Id 15 | * 16 | * @param id 17 | * @return 18 | */ 19 | CustomerBean fetchCustomerDetails(Long id); 20 | 21 | /** 22 | * Fetch Customer Orders 23 | * 24 | * @param customerId 25 | * @return 26 | */ 27 | List fetchCustomerOrders(Long customerId); 28 | 29 | /** 30 | * Fetch customer orders 31 | * 32 | * @param orderId 33 | * @return 34 | */ 35 | CustomerOrdersBean fetchCustomerOrder(Long orderId); 36 | 37 | /** 38 | * Add Cusotmer 39 | * 40 | * @param customer 41 | * @return 42 | */ 43 | CustomerBean addCustomer(CustomerBean customer); 44 | 45 | /** 46 | * Create cusotmer orders 47 | * @param customerOrders 48 | */ 49 | void createCustomerOrder(CustomerOrdersBean customerOrders); 50 | 51 | /** 52 | * Update customer order status 53 | * 54 | * @param orderId 55 | * @param orderStatus 56 | */ 57 | void updateCustomerOrderStatus(Long orderId, OrderStatus orderStatus); 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /GatewayService/src/main/java/com/eshop/gateway/config/GatewayConfig.java: -------------------------------------------------------------------------------- 1 | package com.eshop.gateway.config; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.boot.builder.SpringApplicationBuilder; 7 | import org.springframework.boot.orm.jpa.EntityScan; 8 | import org.springframework.boot.web.support.SpringBootServletInitializer; 9 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 10 | import org.springframework.cloud.netflix.feign.EnableFeignClients; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.ComponentScan; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.web.client.RestTemplate; 15 | 16 | @Configuration 17 | @EnableAutoConfiguration 18 | @ComponentScan(basePackages = {"com.eshop.gateway"}) 19 | @SpringBootApplication 20 | @EnableEurekaClient 21 | @EnableFeignClients(basePackages = "com.eshop.gateway.client") 22 | public class GatewayConfig extends SpringBootServletInitializer { 23 | 24 | @Bean 25 | public RestTemplate restTemplate() { 26 | return new RestTemplate(); 27 | } 28 | 29 | @Override 30 | protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 31 | return application.sources(GatewayConfig.class); 32 | } 33 | 34 | public static void main(String[] args) { 35 | SpringApplication.run(GatewayConfig.class, args); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ProductService/src/main/java/com/eshop/product/config/ProductConfig.java: -------------------------------------------------------------------------------- 1 | package com.eshop.product.config; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.boot.builder.SpringApplicationBuilder; 7 | import org.springframework.boot.autoconfigure.domain.EntityScan; 8 | import org.springframework.boot.web.support.SpringBootServletInitializer; 9 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 10 | import org.springframework.context.annotation.ComponentScan; 11 | import org.springframework.context.annotation.Configuration; 12 | import org.springframework.context.annotation.aspectj.EnableSpringConfigured; 13 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 14 | import org.springframework.transaction.annotation.EnableTransactionManagement; 15 | 16 | import java.util.Arrays; 17 | 18 | @Configuration 19 | @ComponentScan(basePackages = {"com.eshop.product","com.eshop.common.config"}) 20 | @EntityScan(basePackages = "com.eshop.product.domain") 21 | @EnableJpaRepositories(basePackages = "com.eshop.product.repository") 22 | @EnableTransactionManagement 23 | @EnableSpringConfigured 24 | @EnableAutoConfiguration 25 | @EnableEurekaClient 26 | @SpringBootApplication 27 | public class ProductConfig extends SpringBootServletInitializer { 28 | 29 | @Override 30 | protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 31 | return application.sources(ProductConfig.class); 32 | } 33 | 34 | public static void main(String[] args) { 35 | SpringApplication.run(ProductConfig.class, args); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /CustomerService/src/main/java/com/eshop/user/listener/MessageListener.java: -------------------------------------------------------------------------------- 1 | package com.eshop.user.listener; 2 | 3 | import com.eshop.common.beans.CustomerOrdersBean; 4 | import com.eshop.common.beans.Event; 5 | import com.eshop.common.enums.OrderStatus; 6 | import com.eshop.user.service.CustomerService; 7 | import com.fasterxml.jackson.databind.ObjectMapper; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.kafka.annotation.KafkaListener; 10 | import org.springframework.stereotype.Component; 11 | 12 | import java.io.IOException; 13 | 14 | /** 15 | * Created by arun_subramonian on 12/21/16. 16 | */ 17 | @Component 18 | public class MessageListener { 19 | 20 | @Autowired 21 | private ObjectMapper objectMapper; 22 | 23 | @Autowired 24 | private CustomerService customerService; 25 | 26 | 27 | @KafkaListener(topics = "ORDER_CREATED") 28 | public void orderCreatedListener(String message) { 29 | try { 30 | Event event = objectMapper.readValue(message, Event.class); 31 | CustomerOrdersBean customerOrder = new CustomerOrdersBean(); 32 | customerOrder.setCustomerId(event.getCustomerId()); 33 | customerOrder.setOrderId(event.getOrderId()); 34 | customerOrder.setOrderStatus(OrderStatus.PLACED); 35 | customerService.createCustomerOrder(customerOrder); 36 | } catch (IOException e) { 37 | e.printStackTrace(); 38 | } 39 | 40 | } 41 | 42 | @KafkaListener(topics = "ORDER_SHIPPED") 43 | public void orderShippedListener(String message) { 44 | try { 45 | Event event = objectMapper.readValue(message, Event.class); 46 | customerService.updateCustomerOrderStatus(event.getOrderId(), OrderStatus.SHIPPED); 47 | } catch (IOException e) { 48 | e.printStackTrace(); 49 | } 50 | 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /OrderService/src/main/java/com/eshop/order/domain/Order.java: -------------------------------------------------------------------------------- 1 | package com.eshop.order.domain; 2 | 3 | import com.eshop.common.enums.OrderStatus; 4 | 5 | import javax.persistence.*; 6 | import java.util.Collections; 7 | import java.util.HashSet; 8 | import java.util.Set; 9 | 10 | @Entity 11 | @Table(name="ORDERS") 12 | @SequenceGenerator(name = "ORDER_SEQ", sequenceName = "ORDER_SEQ", allocationSize = 1) 13 | public class Order { 14 | 15 | @Id 16 | @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ORDER_SEQ") 17 | private Long id; 18 | 19 | private Long customerId; 20 | 21 | @Enumerated(EnumType.STRING) 22 | private OrderStatus status; 23 | 24 | private Double cost; 25 | 26 | @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "order") 27 | private Set orderDetails; 28 | 29 | public Long getId() { 30 | return id; 31 | } 32 | 33 | public void setId(Long id) { 34 | this.id = id; 35 | } 36 | 37 | public Long getCustomerId() { 38 | return customerId; 39 | } 40 | 41 | public void setCustomerId(Long customerId) { 42 | this.customerId = customerId; 43 | } 44 | 45 | public OrderStatus getStatus() { 46 | return status; 47 | } 48 | 49 | public void setStatus(OrderStatus status) { 50 | this.status = status; 51 | } 52 | 53 | public Double getCost() { 54 | return cost; 55 | } 56 | 57 | public void setCost(Double cost) { 58 | this.cost = cost; 59 | } 60 | 61 | public Set getOrderDetails() { 62 | if (orderDetails == null || orderDetails.size() == 0) { 63 | orderDetails = new HashSet<>(); 64 | } 65 | return orderDetails; 66 | } 67 | 68 | public void setOrderDetails(Set orderDetails) { 69 | this.orderDetails = orderDetails; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /ShippingService/src/main/java/com/eshop/shipping/config/ShippingConfig.java: -------------------------------------------------------------------------------- 1 | package com.eshop.shipping.config; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.boot.autoconfigure.domain.EntityScan; 7 | import org.springframework.boot.builder.SpringApplicationBuilder; 8 | import org.springframework.boot.web.support.SpringBootServletInitializer; 9 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 10 | import org.springframework.context.annotation.ComponentScan; 11 | import org.springframework.context.annotation.Configuration; 12 | import org.springframework.context.annotation.aspectj.EnableSpringConfigured; 13 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 14 | import org.springframework.kafka.annotation.EnableKafka; 15 | import org.springframework.kafka.core.DefaultKafkaProducerFactory; 16 | import org.springframework.kafka.core.KafkaTemplate; 17 | import org.springframework.kafka.core.ProducerFactory; 18 | import org.springframework.transaction.annotation.EnableTransactionManagement; 19 | 20 | 21 | @Configuration 22 | @ComponentScan(basePackages = {"com.eshop.shipping","com.eshop.common.config"}) 23 | @EntityScan(basePackages = "com.eshop.shipping.domain") 24 | @EnableJpaRepositories(basePackages = "com.eshop.shipping.repository") 25 | @EnableTransactionManagement 26 | @EnableSpringConfigured 27 | @EnableAutoConfiguration 28 | @EnableKafka 29 | @EnableEurekaClient 30 | @SpringBootApplication 31 | public class ShippingConfig extends SpringBootServletInitializer { 32 | 33 | @Override 34 | protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 35 | return application.sources(ShippingConfig.class); 36 | } 37 | 38 | public static void main(String[] args) { 39 | SpringApplication.run(ShippingConfig.class, args); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ShippingService/src/main/java/com/eshop/shipping/service/impl/ShippingServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.eshop.shipping.service.impl; 2 | 3 | import com.eshop.common.beans.Event; 4 | import com.eshop.common.enums.ShippingStatus; 5 | import com.eshop.shipping.domain.Shipping; 6 | import com.eshop.shipping.repository.ShippingRepository; 7 | import com.eshop.shipping.service.ShippingService; 8 | import com.fasterxml.jackson.core.JsonProcessingException; 9 | import com.fasterxml.jackson.databind.ObjectMapper; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.kafka.core.KafkaTemplate; 12 | import org.springframework.stereotype.Service; 13 | 14 | import javax.annotation.Resource; 15 | 16 | /** 17 | * Created by arun_subramonian on 12/19/16. 18 | */ 19 | @Service 20 | public class ShippingServiceImpl implements ShippingService { 21 | 22 | @Resource 23 | private ShippingRepository shippingRepository; 24 | 25 | @Autowired 26 | private KafkaTemplate kafkaTemplate; 27 | 28 | @Autowired 29 | private ObjectMapper objectMapper; 30 | 31 | @Override 32 | public void createShippingRequest(Long orderId) { 33 | Shipping shipping = new Shipping(); 34 | shipping.setOrderId(orderId); 35 | shipping.setStatus(ShippingStatus.SHIPPED); 36 | shipping = shippingRepository.save(shipping); 37 | broadcastOrderShippedEvent(shipping); 38 | } 39 | 40 | @Override 41 | public void acknowledgeDelivery(Long shippingId) { 42 | Shipping shipping = shippingRepository.findOne(shippingId); 43 | shipping.setStatus(ShippingStatus.DELIVERED); 44 | shippingRepository.save(shipping); 45 | } 46 | 47 | private void broadcastOrderShippedEvent(Shipping shipping) { 48 | Event event = new Event(); 49 | event.setOrderId(shipping.getOrderId()); 50 | try { 51 | kafkaTemplate.send("ORDER_SHIPPED", objectMapper.writeValueAsString(event)); 52 | } catch (JsonProcessingException e) { 53 | e.printStackTrace(); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /GatewayService/src/main/java/com/eshop/gateway/repository/impl/GatewayRepositoryImpl.java: -------------------------------------------------------------------------------- 1 | package com.eshop.gateway.repository.impl; 2 | 3 | import com.eshop.common.beans.CustomerBean; 4 | import com.eshop.common.beans.CustomerOrdersBean; 5 | import com.eshop.common.beans.OrderBean; 6 | import com.eshop.common.beans.ProductBean; 7 | import com.eshop.gateway.client.CustomerClient; 8 | import com.eshop.gateway.client.OrderClient; 9 | import com.eshop.gateway.client.ProductClient; 10 | import com.eshop.gateway.client.ShippingClient; 11 | import com.eshop.gateway.repository.GatewayRepository; 12 | import com.netflix.discovery.EurekaClient; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.core.ParameterizedTypeReference; 15 | import org.springframework.core.env.Environment; 16 | import org.springframework.http.*; 17 | import org.springframework.stereotype.Repository; 18 | import org.springframework.web.client.RestTemplate; 19 | 20 | import java.util.List; 21 | 22 | /** 23 | * Created by arun_subramonian on 12/23/16. 24 | */ 25 | @Repository 26 | public class GatewayRepositoryImpl implements GatewayRepository { 27 | 28 | @Autowired 29 | private ProductClient productClient; 30 | 31 | @Autowired 32 | private CustomerClient customerClient; 33 | 34 | @Autowired 35 | private OrderClient orderClient; 36 | 37 | @Autowired 38 | private ShippingClient shippingClient; 39 | 40 | @Override 41 | public CustomerBean fetchCustomerDetails(Long id) { 42 | return customerClient.fetchCustomerDetails(id); 43 | } 44 | 45 | @Override 46 | public List fetchCustomerOrders(Long id) { 47 | return customerClient.fetchCustomerOrders(id); 48 | } 49 | 50 | @Override 51 | public CustomerBean addCustomer(CustomerBean customer) { 52 | return customerClient.addCustomer(customer); 53 | } 54 | 55 | @Override 56 | public List fetchAllProducts() { 57 | return productClient.fetchAllProducts(); 58 | } 59 | 60 | @Override 61 | public OrderBean createOrder(OrderBean orderBean) { 62 | return orderClient.createOrder(orderBean); 63 | } 64 | 65 | @Override 66 | public void createShipping(Long id) { 67 | shippingClient.createShipping(id); 68 | } 69 | 70 | @Override 71 | public void acknowledgeDelivery(Long shippingId) { 72 | shippingClient.acknowledgeDelivery(shippingId); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /OrderService/src/main/java/com/eshop/order/config/OrderConfig.java: -------------------------------------------------------------------------------- 1 | package com.eshop.order.config; 2 | 3 | 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.beans.factory.annotation.Qualifier; 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 8 | import org.springframework.boot.autoconfigure.SpringBootApplication; 9 | import org.springframework.boot.autoconfigure.domain.EntityScan; 10 | import org.springframework.boot.builder.SpringApplicationBuilder; 11 | import org.springframework.boot.web.support.SpringBootServletInitializer; 12 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 13 | import org.springframework.context.annotation.Bean; 14 | import org.springframework.context.annotation.ComponentScan; 15 | import org.springframework.context.annotation.Configuration; 16 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 17 | import org.springframework.kafka.annotation.EnableKafka; 18 | import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; 19 | import org.springframework.kafka.core.*; 20 | import org.springframework.transaction.annotation.EnableTransactionManagement; 21 | 22 | import java.util.Arrays; 23 | import java.util.HashMap; 24 | import java.util.Map; 25 | 26 | @Configuration 27 | @ComponentScan(basePackages = {"com.eshop.order", "com.eshop.common.config"}) 28 | @EntityScan(basePackages = "com.eshop.order.domain") 29 | @EnableJpaRepositories(basePackages = "com.eshop.order.repository") 30 | @EnableTransactionManagement 31 | @EnableAutoConfiguration 32 | @EnableKafka 33 | @EnableEurekaClient 34 | @SpringBootApplication 35 | public class OrderConfig extends SpringBootServletInitializer { 36 | 37 | @Autowired 38 | @Qualifier("kafkaOrderListener") 39 | private ConsumerFactory consumerFactory; 40 | 41 | @Bean 42 | public ConcurrentKafkaListenerContainerFactory kafkaListenerContainerFactory() { 43 | ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); 44 | factory.setConsumerFactory(consumerFactory); 45 | return factory; 46 | } 47 | 48 | @Override 49 | protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 50 | return application.sources(OrderConfig.class); 51 | } 52 | 53 | public static void main(String[] args) { 54 | SpringApplication.run(OrderConfig.class, args); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /CustomerService/src/main/java/com/eshop/user/config/CustomerConfig.java: -------------------------------------------------------------------------------- 1 | package com.eshop.user.config; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.beans.factory.annotation.Qualifier; 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | import org.springframework.boot.autoconfigure.domain.EntityScan; 9 | import org.springframework.boot.builder.SpringApplicationBuilder; 10 | import org.springframework.boot.web.support.SpringBootServletInitializer; 11 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 12 | import org.springframework.context.annotation.Bean; 13 | import org.springframework.context.annotation.ComponentScan; 14 | import org.springframework.context.annotation.Configuration; 15 | import org.springframework.context.annotation.aspectj.EnableSpringConfigured; 16 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 17 | import org.springframework.kafka.annotation.EnableKafka; 18 | import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; 19 | import org.springframework.kafka.core.ConsumerFactory; 20 | import org.springframework.kafka.core.DefaultKafkaConsumerFactory; 21 | import org.springframework.transaction.annotation.EnableTransactionManagement; 22 | 23 | @Configuration 24 | @ComponentScan(basePackages = {"com.eshop.user","com.eshop.common.config"}) 25 | @EntityScan(basePackages = "com.eshop.user.domain") 26 | @EnableJpaRepositories(basePackages = "com.eshop.user.repository") 27 | @EnableTransactionManagement 28 | @EnableAutoConfiguration 29 | @EnableKafka 30 | @EnableEurekaClient 31 | @SpringBootApplication 32 | public class CustomerConfig extends SpringBootServletInitializer { 33 | 34 | @Autowired 35 | @Qualifier("kafkaCustomerListener") 36 | private ConsumerFactory consumerFactory; 37 | 38 | @Bean 39 | public ConcurrentKafkaListenerContainerFactory kafkaListenerContainerFactory() { 40 | ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); 41 | factory.setConsumerFactory(consumerFactory); 42 | return factory; 43 | } 44 | 45 | @Override 46 | protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 47 | return application.sources(CustomerConfig.class); 48 | } 49 | 50 | public static void main(String[] args) { 51 | SpringApplication.run(CustomerConfig.class, args); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /CustomerService/src/main/java/com/eshop/user/rest/impl/CustomerRestServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.eshop.user.rest.impl; 2 | 3 | import com.eshop.common.beans.CustomerBean; 4 | import com.eshop.common.beans.CustomerOrdersBean; 5 | import com.eshop.user.rest.CustomerRestService; 6 | import com.eshop.user.service.CustomerService; 7 | import org.jsondoc.core.annotation.ApiBodyObject; 8 | import org.jsondoc.core.annotation.ApiHeader; 9 | import org.jsondoc.core.annotation.ApiHeaders; 10 | import org.jsondoc.core.annotation.ApiMethod; 11 | import org.jsondoc.core.annotation.ApiPathParam; 12 | import org.jsondoc.core.annotation.ApiResponseObject; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.http.HttpStatus; 15 | import org.springframework.web.bind.annotation.*; 16 | 17 | import java.util.List; 18 | 19 | import static org.springframework.http.HttpHeaders.ACCEPT; 20 | import static org.springframework.http.HttpHeaders.CONTENT_TYPE; 21 | 22 | 23 | @RestController 24 | @RequestMapping(value = "/services/customer") 25 | public class CustomerRestServiceImpl implements CustomerRestService { 26 | 27 | @Autowired 28 | private CustomerService customerService; 29 | 30 | @RequestMapping(value= "/{id}", method = RequestMethod.GET) 31 | @ApiMethod(description = "Fetch Customer Details", responsestatuscode = "200 - OK") 32 | @ApiHeaders(headers = { 33 | @ApiHeader(name = ACCEPT), 34 | @ApiHeader(name = CONTENT_TYPE) 35 | }) 36 | @ResponseStatus(HttpStatus.OK) 37 | @ApiResponseObject 38 | public CustomerBean fetchCustomerDetails(@ApiPathParam(name = "id") @PathVariable Long id) { 39 | return customerService.fetchCustomerDetails(id); 40 | } 41 | 42 | @RequestMapping(value= "/{id}/orders", method = RequestMethod.GET) 43 | @ApiMethod(description = "Fetch Customer Orders", responsestatuscode = "200 - OK") 44 | @ApiHeaders(headers = { 45 | @ApiHeader(name = ACCEPT), 46 | @ApiHeader(name = CONTENT_TYPE) 47 | }) 48 | @ResponseStatus(HttpStatus.OK) 49 | @ApiResponseObject 50 | public List fetchCustomerOrders(@ApiPathParam(name = "id") @PathVariable Long id) { 51 | return customerService.fetchCustomerOrders(id); 52 | } 53 | 54 | @RequestMapping(method = RequestMethod.POST) 55 | @ApiMethod(description = "Add Customer", responsestatuscode = "200 - OK") 56 | @ApiHeaders(headers = { 57 | @ApiHeader(name = ACCEPT), 58 | @ApiHeader(name = CONTENT_TYPE) 59 | }) 60 | @ResponseStatus(HttpStatus.OK) 61 | @ApiResponseObject 62 | public CustomerBean addCustomer(@ApiBodyObject @RequestBody CustomerBean customer) { 63 | return customerService.addCustomer(customer); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /GatewayService/src/main/java/com/eshop/gateway/rest/impl/GatewayRestServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.eshop.gateway.rest.impl; 2 | 3 | import com.eshop.common.beans.CustomerBean; 4 | import com.eshop.common.beans.CustomerOrdersBean; 5 | import com.eshop.common.beans.OrderBean; 6 | import com.eshop.common.beans.ProductBean; 7 | import com.eshop.gateway.repository.GatewayRepository; 8 | import com.eshop.gateway.rest.GatewayRestService; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.http.*; 11 | import org.springframework.web.bind.annotation.*; 12 | 13 | import java.util.List; 14 | 15 | /** 16 | * Created by arun_subramonian on 12/23/16. 17 | */ 18 | @RestController 19 | @RequestMapping(value = "/services/gateway") 20 | public class GatewayRestServiceImpl implements GatewayRestService { 21 | 22 | @Autowired 23 | private GatewayRepository gatewayRepository; 24 | 25 | @Override 26 | @RequestMapping(value= "/customer/{id}", method = RequestMethod.GET) 27 | @ResponseStatus(HttpStatus.OK) 28 | public CustomerBean fetchCustomerDetails(@PathVariable Long id) { 29 | return gatewayRepository.fetchCustomerDetails(id); 30 | } 31 | 32 | @Override 33 | @RequestMapping(value= "/customer/{id}/orders", method = RequestMethod.GET) 34 | @ResponseStatus(HttpStatus.OK) 35 | public List fetchCustomerOrders(@PathVariable Long id) { 36 | return gatewayRepository.fetchCustomerOrders(id); 37 | } 38 | 39 | @Override 40 | @RequestMapping(value= "/customer", method = RequestMethod.POST) 41 | @ResponseStatus(HttpStatus.OK) 42 | public CustomerBean addCustomer(@RequestBody CustomerBean customer) { 43 | return gatewayRepository.addCustomer(customer); 44 | } 45 | 46 | @Override 47 | @RequestMapping(value= "/product", method = RequestMethod.GET) 48 | @ResponseStatus(HttpStatus.OK) 49 | public List fetchAllProducts() { 50 | return gatewayRepository.fetchAllProducts(); 51 | } 52 | 53 | @Override 54 | @RequestMapping(value= "/order", method = RequestMethod.POST) 55 | @ResponseStatus(HttpStatus.OK) 56 | public OrderBean createOrder(@RequestBody OrderBean orderBean) { 57 | return gatewayRepository.createOrder(orderBean); 58 | } 59 | 60 | @Override 61 | @RequestMapping(value= "/shipping/order/{id}", method = RequestMethod.POST) 62 | @ResponseStatus(HttpStatus.OK) 63 | public void createShipping(@PathVariable Long id) { 64 | gatewayRepository.createShipping(id); 65 | } 66 | 67 | @Override 68 | @RequestMapping(value= "/shipping/{id}", method = RequestMethod.POST) 69 | @ResponseStatus(HttpStatus.OK) 70 | public void acknowledgeDelivery(@PathVariable Long shippingId) { 71 | gatewayRepository.acknowledgeDelivery(shippingId); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /CustomerService/src/main/java/com/eshop/user/service/impl/CustomerServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.eshop.user.service.impl; 2 | 3 | import com.eshop.common.beans.CustomerBean; 4 | import com.eshop.common.beans.CustomerOrdersBean; 5 | import com.eshop.common.enums.OrderStatus; 6 | import com.eshop.user.domain.Customer; 7 | import com.eshop.user.domain.CustomerOrders; 8 | import com.eshop.user.repository.CustomerOrderRepository; 9 | import com.eshop.user.repository.CustomerRepository; 10 | import com.eshop.user.service.CustomerService; 11 | import org.dozer.Mapper; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.stereotype.Service; 14 | import org.springframework.transaction.annotation.Transactional; 15 | 16 | import javax.annotation.Resource; 17 | import java.util.ArrayList; 18 | import java.util.List; 19 | import java.util.stream.Collectors; 20 | 21 | 22 | @Service 23 | public class CustomerServiceImpl implements CustomerService { 24 | 25 | @Resource 26 | private CustomerRepository customerRepository; 27 | 28 | @Resource 29 | private CustomerOrderRepository customerOrderRepository; 30 | 31 | @Autowired 32 | private Mapper mapper; 33 | 34 | @Override 35 | public CustomerBean fetchCustomerDetails(Long id) { 36 | Customer customer = customerRepository.findOne(id); 37 | return mapper.map(customer, CustomerBean.class); 38 | } 39 | 40 | @Override 41 | public List fetchCustomerOrders(Long customerId) { 42 | List customerOrders = customerOrderRepository.findByCustomerId(customerId); 43 | List customerOrderBeans = customerOrders.stream().map( s -> mapper.map(s, CustomerOrdersBean.class)).collect(Collectors.toList()); 44 | return customerOrderBeans; 45 | } 46 | 47 | @Override 48 | public CustomerOrdersBean fetchCustomerOrder(Long orderId) { 49 | CustomerOrders customerOrder = customerOrderRepository.findByOrderId(orderId); 50 | return mapper.map(customerOrder, CustomerOrdersBean.class); 51 | } 52 | 53 | @Override 54 | @Transactional 55 | public void createCustomerOrder(CustomerOrdersBean customerOrders) { 56 | CustomerOrders customerOrder = mapper.map(customerOrders, CustomerOrders.class); 57 | customerOrderRepository.save(customerOrder); 58 | } 59 | 60 | @Override 61 | @Transactional 62 | public void updateCustomerOrderStatus(Long orderId, OrderStatus orderStatus) { 63 | CustomerOrders customerOrder = customerOrderRepository.findByOrderId(orderId); 64 | customerOrder.setOrderStatus(orderStatus); 65 | customerOrderRepository.save(customerOrder); 66 | } 67 | 68 | @Override 69 | @Transactional 70 | public CustomerBean addCustomer(CustomerBean customerBean) { 71 | Customer customer = mapper.map(customerBean, Customer.class); 72 | customer = customerRepository.save(customer); 73 | return mapper.map(customer, CustomerBean.class); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /OrderService/src/main/java/com/eshop/order/service/impl/OrderServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.eshop.order.service.impl; 2 | 3 | import com.eshop.common.beans.Event; 4 | import com.eshop.common.beans.OrderBean; 5 | import com.eshop.common.enums.OrderStatus; 6 | import com.eshop.order.domain.Order; 7 | import com.eshop.order.domain.OrderDetails; 8 | import com.eshop.order.repository.OrderRepository; 9 | import com.eshop.order.service.OrderService; 10 | import com.fasterxml.jackson.core.JsonProcessingException; 11 | import com.fasterxml.jackson.databind.ObjectMapper; 12 | import org.dozer.Mapper; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.kafka.core.KafkaTemplate; 15 | import org.springframework.stereotype.Service; 16 | import org.springframework.transaction.annotation.Transactional; 17 | 18 | import javax.annotation.Resource; 19 | 20 | /** 21 | * Created by arun_subramonian on 12/19/16. 22 | */ 23 | @Service 24 | public class OrderServiceImpl implements OrderService { 25 | 26 | @Autowired 27 | private Mapper mapper; 28 | 29 | @Resource 30 | private OrderRepository orderRepository; 31 | 32 | @Autowired 33 | private KafkaTemplate kafkaTemplate; 34 | 35 | @Autowired 36 | private ObjectMapper objectMapper; 37 | 38 | @Override 39 | public OrderBean findOrder(Long orderId) { 40 | Order order = orderRepository.findOne(orderId); 41 | OrderBean orderBean = mapper.map(order, OrderBean.class); 42 | return orderBean; 43 | } 44 | 45 | @Override 46 | @Transactional 47 | public OrderBean createOrder(OrderBean orderBean) { 48 | Order order = updateOrderDetails(orderBean); 49 | order = orderRepository.save(order); 50 | broadcastOrderCreatedEvent(order); 51 | return mapper.map(order, OrderBean.class); 52 | } 53 | 54 | @Override 55 | @Transactional 56 | public void updateOrderStatus(Long orderId, OrderStatus orderStatus) { 57 | Order order = orderRepository.findOne(orderId); 58 | order.setStatus(orderStatus); 59 | orderRepository.save(order); 60 | } 61 | 62 | private void broadcastOrderCreatedEvent(Order order) { 63 | Event event = new Event(); 64 | event.setOrderId(order.getId()); 65 | event.setCustomerId(order.getCustomerId()); 66 | try { 67 | kafkaTemplate.send("ORDER_CREATED", objectMapper.writeValueAsString(event)); 68 | } catch (JsonProcessingException e) { 69 | e.printStackTrace(); 70 | } 71 | } 72 | 73 | private Order updateOrderDetails(OrderBean orderBean) { 74 | Order orderCreated = mapper.map(orderBean, Order.class); 75 | for (Long productId: orderBean.getProductIds()) { 76 | OrderDetails orderDetail = new OrderDetails(); 77 | orderDetail.setProductId(productId); 78 | orderDetail.setOrder(orderCreated); 79 | orderCreated.getOrderDetails().add(orderDetail); 80 | } 81 | return orderCreated; 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /CommonService/src/main/java/com/eshop/common/config/KafkaConfig.java: -------------------------------------------------------------------------------- 1 | package com.eshop.common.config; 2 | 3 | import org.apache.kafka.clients.consumer.ConsumerConfig; 4 | import org.apache.kafka.clients.producer.ProducerConfig; 5 | import org.apache.kafka.common.serialization.IntegerDeserializer; 6 | import org.apache.kafka.common.serialization.IntegerSerializer; 7 | import org.apache.kafka.common.serialization.StringDeserializer; 8 | import org.apache.kafka.common.serialization.StringSerializer; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; 12 | import org.springframework.kafka.core.*; 13 | 14 | import java.util.HashMap; 15 | import java.util.Map; 16 | 17 | /** 18 | * Created by arun_subramonian on 12/21/16. 19 | */ 20 | @Configuration 21 | public class KafkaConfig { 22 | 23 | @Bean 24 | public ProducerFactory producerFactory() { 25 | return new DefaultKafkaProducerFactory<>(producerConfigs()); 26 | } 27 | 28 | public Map producerConfigs() { 29 | Map props = new HashMap<>(); 30 | props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9093,localhost:9094,localhost:9092"); 31 | props.put(ProducerConfig.RETRIES_CONFIG, 0); 32 | props.put(ProducerConfig.BATCH_SIZE_CONFIG, 16384); 33 | props.put(ProducerConfig.LINGER_MS_CONFIG, 1); 34 | props.put(ProducerConfig.BUFFER_MEMORY_CONFIG, 33554432); 35 | props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, IntegerSerializer.class); 36 | props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class); 37 | return props; 38 | } 39 | 40 | @Bean 41 | public KafkaTemplate kafkaTemplate() { 42 | return new KafkaTemplate<>(producerFactory()); 43 | } 44 | 45 | @Bean(name = "kafkaOrderListener") 46 | public ConsumerFactory orderConsumerFactory() { 47 | return new DefaultKafkaConsumerFactory<>(consumerConfigs("order-consumer-group")); 48 | } 49 | 50 | @Bean(name = "kafkaCustomerListener") 51 | public ConsumerFactory customerConsumerFactory() { 52 | return new DefaultKafkaConsumerFactory<>(consumerConfigs("customer-consumer-group")); 53 | } 54 | 55 | public Map consumerConfigs(String consumerGroup) { 56 | Map props = new HashMap<>(); 57 | props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9093,localhost:9094,localhost:9092"); 58 | props.put(ConsumerConfig.GROUP_ID_CONFIG, consumerGroup); 59 | props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, true); 60 | props.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, "100"); 61 | props.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, "15000"); 62 | props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, IntegerDeserializer.class); 63 | props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); 64 | return props; 65 | } 66 | } 67 | --------------------------------------------------------------------------------