├── .gitignore
├── README.md
├── section-01
├── README.md
└── waiter-service
│ ├── .gitignore
│ ├── pom.xml
│ └── src
│ ├── main
│ ├── java
│ │ └── takeout
│ │ │ └── waiterservice
│ │ │ ├── DataInitializerRunner.java
│ │ │ ├── TakeOutOrder.java
│ │ │ ├── TakeOutOrderRepository.java
│ │ │ ├── WaiterServiceApplication.java
│ │ │ └── WaiterServiceController.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── takeout
│ └── waiterservice
│ └── WaiterServiceApplicationTests.java
├── section-02
├── README.md
└── waiter-service
│ ├── .gitignore
│ ├── pom.xml
│ └── src
│ ├── main
│ ├── java
│ │ └── takeout
│ │ │ └── waiterservice
│ │ │ ├── DataInitializerRunner.java
│ │ │ ├── WaiterServiceApplication.java
│ │ │ ├── controller
│ │ │ ├── ExceptionControllerAdvice.java
│ │ │ ├── OrderController.java
│ │ │ └── PaymentController.java
│ │ │ ├── model
│ │ │ ├── Payment.java
│ │ │ └── TakeOutOrder.java
│ │ │ ├── repository
│ │ │ ├── PaymentRepository.java
│ │ │ └── TakeOutOrderRepository.java
│ │ │ └── service
│ │ │ ├── OrderService.java
│ │ │ └── PaymentService.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── takeout
│ └── waiterservice
│ └── WaiterServiceApplicationTests.java
├── section-03
├── README.md
└── customer-service
│ ├── .gitignore
│ ├── pom.xml
│ └── src
│ ├── main
│ ├── java
│ │ └── takeout
│ │ │ └── customerservice
│ │ │ ├── CustomerServiceApplication.java
│ │ │ ├── SimpleOrderRunner.java
│ │ │ └── model
│ │ │ ├── Order.java
│ │ │ └── Payment.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── takeout
│ └── customerservice
│ └── CustomerServiceApplicationTests.java
├── section-04
├── README.md
├── customer-service
│ ├── .gitignore
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── takeout
│ │ │ │ └── customerservice
│ │ │ │ ├── CustomerServiceApplication.java
│ │ │ │ ├── SimpleOrderRunner.java
│ │ │ │ └── model
│ │ │ │ └── TakeOutOrder.java
│ │ └── resources
│ │ │ └── application.properties
│ │ └── test
│ │ └── java
│ │ └── takeout
│ │ └── customerservice
│ │ └── CustomerServiceApplicationTests.java
└── waiter-service
│ ├── .gitignore
│ ├── pom.xml
│ └── src
│ ├── main
│ ├── java
│ │ └── takeout
│ │ │ └── waiterservice
│ │ │ ├── DataInitializerRunner.java
│ │ │ ├── WaiterServiceApplication.java
│ │ │ ├── controller
│ │ │ ├── ExceptionControllerAdvice.java
│ │ │ ├── OrderController.java
│ │ │ └── PaymentController.java
│ │ │ ├── model
│ │ │ ├── Payment.java
│ │ │ └── TakeOutOrder.java
│ │ │ ├── repository
│ │ │ ├── PaymentRepository.java
│ │ │ └── TakeOutOrderRepository.java
│ │ │ └── service
│ │ │ ├── OrderService.java
│ │ │ └── PaymentService.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── takeout
│ └── waiterservice
│ └── WaiterServiceApplicationTests.java
├── section-05
├── README.md
├── customer-service
│ ├── .gitignore
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── takeout
│ │ │ │ └── customerservice
│ │ │ │ ├── CustomerServiceApplication.java
│ │ │ │ ├── SimpleOrderRunner.java
│ │ │ │ └── model
│ │ │ │ ├── Order.java
│ │ │ │ └── Payment.java
│ │ └── resources
│ │ │ ├── application.properties
│ │ │ └── bootstrap.properties
│ │ └── test
│ │ └── java
│ │ └── takeout
│ │ └── customerservice
│ │ └── CustomerServiceApplicationTests.java
├── eureka-server
│ ├── .gitignore
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── takeout
│ │ │ │ └── eurekaserver
│ │ │ │ └── EurekaServerApplication.java
│ │ └── resources
│ │ │ └── application.properties
│ │ └── test
│ │ └── java
│ │ └── takeout
│ │ └── eurekaserver
│ │ └── EurekaServerApplicationTests.java
└── waiter-service
│ ├── .gitignore
│ ├── pom.xml
│ └── src
│ ├── main
│ ├── java
│ │ └── takeout
│ │ │ └── waiterservice
│ │ │ ├── DataInitializerRunner.java
│ │ │ ├── WaiterServiceApplication.java
│ │ │ ├── controller
│ │ │ ├── ExceptionControllerAdvice.java
│ │ │ ├── OrderController.java
│ │ │ └── PaymentController.java
│ │ │ ├── model
│ │ │ ├── Payment.java
│ │ │ └── TakeOutOrder.java
│ │ │ ├── repository
│ │ │ ├── PaymentRepository.java
│ │ │ └── TakeOutOrderRepository.java
│ │ │ └── service
│ │ │ ├── OrderService.java
│ │ │ └── PaymentService.java
│ └── resources
│ │ ├── application.properties
│ │ └── bootstrap.properties
│ └── test
│ └── java
│ └── takeout
│ └── waiterservice
│ └── WaiterServiceApplicationTests.java
├── section-06
├── README.md
├── customer-service
│ ├── .gitignore
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── takeout
│ │ │ │ └── customerservice
│ │ │ │ ├── CustomerServiceApplication.java
│ │ │ │ ├── SimpleOrderRunner.java
│ │ │ │ └── model
│ │ │ │ ├── Order.java
│ │ │ │ └── Payment.java
│ │ └── resources
│ │ │ ├── application.properties
│ │ │ └── bootstrap.properties
│ │ └── test
│ │ └── java
│ │ └── takeout
│ │ └── customerservice
│ │ └── CustomerServiceApplicationTests.java
└── waiter-service
│ ├── .gitignore
│ ├── pom.xml
│ └── src
│ ├── main
│ ├── java
│ │ └── takeout
│ │ │ └── waiterservice
│ │ │ ├── DataInitializerRunner.java
│ │ │ ├── WaiterServiceApplication.java
│ │ │ ├── controller
│ │ │ ├── ExceptionControllerAdvice.java
│ │ │ ├── OrderController.java
│ │ │ └── PaymentController.java
│ │ │ ├── model
│ │ │ ├── Payment.java
│ │ │ └── TakeOutOrder.java
│ │ │ ├── repository
│ │ │ ├── PaymentRepository.java
│ │ │ └── TakeOutOrderRepository.java
│ │ │ └── service
│ │ │ ├── OrderService.java
│ │ │ └── PaymentService.java
│ └── resources
│ │ ├── application.properties
│ │ └── bootstrap.properties
│ └── test
│ └── java
│ └── takeout
│ └── waiterservice
│ └── WaiterServiceApplicationTests.java
├── section-07
├── README.md
├── customer-service
│ ├── .gitignore
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── takeout
│ │ │ │ └── customerservice
│ │ │ │ ├── CustomerServiceApplication.java
│ │ │ │ ├── SimpleOrderRunner.java
│ │ │ │ ├── TakeOutService.java
│ │ │ │ └── model
│ │ │ │ ├── Order.java
│ │ │ │ └── Payment.java
│ │ └── resources
│ │ │ ├── application.properties
│ │ │ └── bootstrap.properties
│ │ └── test
│ │ └── java
│ │ └── takeout
│ │ └── customerservice
│ │ └── CustomerServiceApplicationTests.java
└── hystrix-dashboard
│ ├── .gitignore
│ ├── pom.xml
│ └── src
│ ├── main
│ ├── java
│ │ └── takeout
│ │ │ └── hystrixdashboard
│ │ │ └── HystrixDashboardApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── takeout
│ └── hystrixdashboard
│ └── HystrixDashboardApplicationTests.java
├── section-08
├── README.md
└── waiter-service
│ ├── .gitignore
│ ├── pom.xml
│ └── src
│ ├── main
│ ├── java
│ │ └── takeout
│ │ │ └── waiterservice
│ │ │ ├── DataInitializerRunner.java
│ │ │ ├── Waiter.java
│ │ │ ├── WaiterServiceApplication.java
│ │ │ ├── controller
│ │ │ ├── ExceptionControllerAdvice.java
│ │ │ ├── OrderController.java
│ │ │ └── PaymentController.java
│ │ │ ├── model
│ │ │ ├── Payment.java
│ │ │ └── TakeOutOrder.java
│ │ │ ├── repository
│ │ │ ├── PaymentRepository.java
│ │ │ └── TakeOutOrderRepository.java
│ │ │ └── service
│ │ │ ├── OrderService.java
│ │ │ └── PaymentService.java
│ └── resources
│ │ ├── application.properties
│ │ └── bootstrap.properties
│ └── test
│ └── java
│ └── takeout
│ └── waiterservice
│ └── WaiterServiceApplicationTests.java
├── section-09
├── README.md
├── chef-service
│ ├── .gitignore
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── takeout
│ │ │ │ └── chefservice
│ │ │ │ ├── ChefServiceApplication.java
│ │ │ │ ├── TakeOutOrder.java
│ │ │ │ └── TakeOutStream.java
│ │ └── resources
│ │ │ └── application.properties
│ │ └── test
│ │ └── java
│ │ └── takeout
│ │ └── chefservice
│ │ └── ChefServiceApplicationTests.java
├── customer-service
│ ├── .gitignore
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── takeout
│ │ │ │ └── customerservice
│ │ │ │ ├── CustomerServiceApplication.java
│ │ │ │ ├── SimpleOrderRunner.java
│ │ │ │ ├── TakeOutStream.java
│ │ │ │ └── model
│ │ │ │ ├── Payment.java
│ │ │ │ └── TakeOutOrder.java
│ │ └── resources
│ │ │ ├── application.properties
│ │ │ └── bootstrap.properties
│ │ └── test
│ │ └── java
│ │ └── takeout
│ │ └── customerservice
│ │ └── CustomerServiceApplicationTests.java
└── waiter-service
│ ├── .gitignore
│ ├── pom.xml
│ └── src
│ ├── main
│ ├── java
│ │ └── takeout
│ │ │ └── waiterservice
│ │ │ ├── DataInitializerRunner.java
│ │ │ ├── TakeOutStream.java
│ │ │ ├── Waiter.java
│ │ │ ├── WaiterServiceApplication.java
│ │ │ ├── controller
│ │ │ ├── ExceptionControllerAdvice.java
│ │ │ ├── OrderController.java
│ │ │ └── PaymentController.java
│ │ │ ├── model
│ │ │ ├── Payment.java
│ │ │ └── TakeOutOrder.java
│ │ │ ├── repository
│ │ │ ├── PaymentRepository.java
│ │ │ └── TakeOutOrderRepository.java
│ │ │ └── service
│ │ │ ├── OrderService.java
│ │ │ └── PaymentService.java
│ └── resources
│ │ ├── application.properties
│ │ └── bootstrap.properties
│ └── test
│ └── java
│ └── takeout
│ └── waiterservice
│ └── WaiterServiceApplicationTests.java
├── section-10
├── README.md
├── chef-service
│ ├── .gitignore
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── takeout
│ │ │ │ └── chefservice
│ │ │ │ ├── ChefServiceApplication.java
│ │ │ │ ├── TakeOutOrder.java
│ │ │ │ └── TakeOutStream.java
│ │ └── resources
│ │ │ ├── application.properties
│ │ │ └── bootstrap.properties
│ │ └── test
│ │ └── java
│ │ └── takeout
│ │ └── chefservice
│ │ └── ChefServiceApplicationTests.java
├── customer-service
│ ├── .gitignore
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── takeout
│ │ │ │ └── customerservice
│ │ │ │ ├── CustomerServiceApplication.java
│ │ │ │ ├── TakeOutStream.java
│ │ │ │ └── model
│ │ │ │ ├── Payment.java
│ │ │ │ └── TakeOutOrder.java
│ │ └── resources
│ │ │ ├── application.properties
│ │ │ └── bootstrap.properties
│ │ └── test
│ │ └── java
│ │ └── takeout
│ │ └── customerservice
│ │ └── CustomerServiceApplicationTests.java
└── waiter-service
│ ├── .gitignore
│ ├── pom.xml
│ └── src
│ ├── main
│ ├── java
│ │ └── takeout
│ │ │ └── waiterservice
│ │ │ ├── DataInitializerRunner.java
│ │ │ ├── TakeOutStream.java
│ │ │ ├── Waiter.java
│ │ │ ├── WaiterServiceApplication.java
│ │ │ ├── controller
│ │ │ ├── ExceptionControllerAdvice.java
│ │ │ ├── OrderController.java
│ │ │ └── PaymentController.java
│ │ │ ├── model
│ │ │ ├── Payment.java
│ │ │ └── TakeOutOrder.java
│ │ │ ├── repository
│ │ │ ├── PaymentRepository.java
│ │ │ └── TakeOutOrderRepository.java
│ │ │ └── service
│ │ │ ├── OrderService.java
│ │ │ └── PaymentService.java
│ └── resources
│ │ ├── application.properties
│ │ └── bootstrap.properties
│ └── test
│ └── java
│ └── takeout
│ └── waiterservice
│ └── WaiterServiceApplicationTests.java
├── section-11
├── README.md
├── chef-service
│ ├── .gitignore
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── docker
│ │ │ └── Dockerfile
│ │ ├── java
│ │ │ └── takeout
│ │ │ │ └── chefservice
│ │ │ │ ├── ChefServiceApplication.java
│ │ │ │ ├── TakeOutOrder.java
│ │ │ │ └── TakeOutStream.java
│ │ └── resources
│ │ │ ├── application.yml
│ │ │ └── bootstrap.yml
│ │ └── test
│ │ └── java
│ │ └── takeout
│ │ └── chefservice
│ │ └── ChefServiceApplicationTests.java
├── customer-service
│ ├── .gitignore
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── docker
│ │ │ └── Dockerfile
│ │ ├── java
│ │ │ └── takeout
│ │ │ │ └── customerservice
│ │ │ │ ├── CustomerServiceApplication.java
│ │ │ │ ├── TakeOutStream.java
│ │ │ │ └── model
│ │ │ │ ├── Payment.java
│ │ │ │ └── TakeOutOrder.java
│ │ └── resources
│ │ │ ├── application.yml
│ │ │ └── bootstrap.yml
│ │ └── test
│ │ └── java
│ │ └── takeout
│ │ └── customerservice
│ │ └── CustomerServiceApplicationTests.java
├── docker-compose.yml
└── waiter-service
│ ├── .gitignore
│ ├── pom.xml
│ └── src
│ ├── main
│ ├── docker
│ │ └── Dockerfile
│ ├── java
│ │ └── takeout
│ │ │ └── waiterservice
│ │ │ ├── DataInitializerRunner.java
│ │ │ ├── TakeOutStream.java
│ │ │ ├── Waiter.java
│ │ │ ├── WaiterServiceApplication.java
│ │ │ ├── controller
│ │ │ ├── ExceptionControllerAdvice.java
│ │ │ ├── OrderController.java
│ │ │ └── PaymentController.java
│ │ │ ├── model
│ │ │ ├── Payment.java
│ │ │ └── TakeOutOrder.java
│ │ │ ├── repository
│ │ │ ├── PaymentRepository.java
│ │ │ └── TakeOutOrderRepository.java
│ │ │ └── service
│ │ │ ├── OrderService.java
│ │ │ └── PaymentService.java
│ └── resources
│ │ ├── application.yml
│ │ └── bootstrap.yml
│ └── test
│ └── java
│ └── takeout
│ └── waiterservice
│ └── WaiterServiceApplicationTests.java
└── section-12
├── README.md
├── customer-service
├── .gitignore
├── pom.xml
└── src
│ ├── main
│ ├── docker
│ │ └── Dockerfile
│ ├── java
│ │ └── takeout
│ │ │ └── customerservice
│ │ │ ├── CustomerServiceApplication.java
│ │ │ └── model
│ │ │ ├── Order.java
│ │ │ └── Payment.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── takeout
│ └── customerservice
│ └── CustomerServiceApplicationTests.java
├── docker-compose.yml
├── istio
├── istio-destination.yml
├── istio-vs-all-v1.yml
├── istio-vs-waiter-abort.yml
├── istio-vs-waiter-delay.yml
├── istio-vs-waiter-percent.yml
└── istio-vs-waiter-v2.yml
├── takeout-aliyun.yml
├── takeout-minikube.yml
└── waiter-service
├── .gitignore
├── pom.xml
└── src
├── main
├── docker
│ └── Dockerfile
├── java
│ └── takeout
│ │ └── waiterservice
│ │ ├── WaiterServiceApplication.java
│ │ ├── controller
│ │ ├── ExceptionControllerAdvice.java
│ │ ├── OrderController.java
│ │ └── PaymentController.java
│ │ ├── model
│ │ ├── Payment.java
│ │ └── TakeOutOrder.java
│ │ ├── repository
│ │ ├── PaymentRepository.java
│ │ └── TakeOutOrderRepository.java
│ │ └── service
│ │ ├── OrderService.java
│ │ └── PaymentService.java
└── resources
│ └── application.properties
└── test
└── java
└── takeout
└── waiterservice
└── WaiterServiceApplicationTests.java
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | pom.xml.tag
3 | pom.xml.releaseBackup
4 | pom.xml.versionsBackup
5 | pom.xml.next
6 | release.properties
7 | dependency-reduced-pom.xml
8 | buildNumber.properties
9 | .mvn/timing.properties
10 |
11 | # Avoid ignoring Maven wrapper jar file (.jar files are usually ignored)
12 | !/.mvn/wrapper/maven-wrapper.jar
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 微服务架构与实战
2 |
3 | QConShanghai 2018深度培训第二天演示代码。
4 | 大会官方页面:[微服务架构与实践](https://2018.qconshanghai.com/training/953)
5 |
6 | ## 代码说明
7 |
8 | * Section 01 - 一个最基本的微服务
9 | * Section 02 - 重构了Section 01的服务,丰富了服务内容
10 | * Section 03 - 为Section 02的服务编写了一个基于RestTemplate的客户端
11 | * Section 04 - 用Spring Data REST重构了Section 02和Section03的代码
12 | * Section 05 - 使用Spring Cloud Netflix,通过Eureka实现服务注册与发现
13 | * Section 06 - 使用Zookeeper代替Section 05的Eureka实现服务注册与发现
14 | * Section 07 - 演示Hystrix断路器
15 | * Section 08 - 使用Zookeeper作为配置中心,加载集中配置
16 | * Section 09 - 增加RabbitMQ,使用Spring Cloud Stream,新增了chef-service
17 | * Section 10 - 演示了Spring Cloud Sleuth的使用,基于OpenZipkin实现服务追踪
18 | * Section 11 - 将Section 10的所有服务打包成Docker镜像,并提供DockerCompose配置
19 | * Section 12 - 基于Section 06重构代码,去除Spring Cloud依赖,演示在阿里云k8s上运行代码,同时也演示了Istio相关的一些功能
20 |
21 |
--------------------------------------------------------------------------------
/section-01/README.md:
--------------------------------------------------------------------------------
1 | # Section 01
2 |
3 | 最简单的一个微服务,包含如下元素:
4 |
5 | 1. 一个Model
6 | 2. 对应的JpaRepository接口
7 | 3. 一个初始化数据的Runner
8 | 4. 一个REST服务
9 |
10 | 其中使用了Spring Boot,通过Lombok简化了模型类的编写。
11 |
--------------------------------------------------------------------------------
/section-01/waiter-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-01/waiter-service/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | takeout
7 | waiter-service
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | waiter-service
12 | a simple microservice demo
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.0.5.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 |
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter-actuator
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-starter-data-jpa
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter-web
39 |
40 |
41 |
42 | com.h2database
43 | h2
44 | runtime
45 |
46 |
47 | org.projectlombok
48 | lombok
49 | true
50 |
51 |
52 | org.springframework.boot
53 | spring-boot-starter-test
54 | test
55 |
56 |
57 |
58 |
59 |
60 |
61 | org.springframework.boot
62 | spring-boot-maven-plugin
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/section-01/waiter-service/src/main/java/takeout/waiterservice/DataInitializerRunner.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.boot.ApplicationArguments;
5 | import org.springframework.boot.ApplicationRunner;
6 | import org.springframework.stereotype.Component;
7 |
8 | import java.util.Date;
9 |
10 | @Component
11 | public class DataInitializerRunner implements ApplicationRunner {
12 | @Autowired
13 | private TakeOutOrderRepository orderRepository;
14 |
15 | @Override
16 | public void run(ApplicationArguments args) throws Exception {
17 | TakeOutOrder order = TakeOutOrder.builder()
18 | .customer("Tony")
19 | .waiter("Steve")
20 | .items("Hamburger")
21 | .createTime(new Date())
22 | .modifyTime(new Date()).build();
23 | orderRepository.save(order);
24 |
25 | order = TakeOutOrder.builder()
26 | .customer("Tony")
27 | .waiter("Bruce")
28 | .items("Sandwich")
29 | .createTime(new Date())
30 | .modifyTime(new Date()).build();
31 | orderRepository.save(order);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/section-01/waiter-service/src/main/java/takeout/waiterservice/TakeOutOrder.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.persistence.Column;
10 | import javax.persistence.Entity;
11 | import javax.persistence.GeneratedValue;
12 | import javax.persistence.Id;
13 | import java.util.Date;
14 |
15 | @Data
16 | @NoArgsConstructor
17 | @AllArgsConstructor
18 | @Builder
19 | @JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler", "fieldHandler"})
20 | @Entity
21 | public class TakeOutOrder {
22 | @Id
23 | @GeneratedValue
24 | private Long id;
25 | private String items;
26 | private String customer;
27 | private String waiter;
28 | @Column(updatable = false)
29 | private Date createTime;
30 | private Date modifyTime;
31 | }
32 |
--------------------------------------------------------------------------------
/section-01/waiter-service/src/main/java/takeout/waiterservice/TakeOutOrderRepository.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 |
5 | public interface TakeOutOrderRepository extends JpaRepository {
6 | }
7 |
--------------------------------------------------------------------------------
/section-01/waiter-service/src/main/java/takeout/waiterservice/WaiterServiceApplication.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class WaiterServiceApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(WaiterServiceApplication.class, args);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/section-01/waiter-service/src/main/java/takeout/waiterservice/WaiterServiceController.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.web.bind.annotation.PathVariable;
5 | import org.springframework.web.bind.annotation.RequestMapping;
6 | import org.springframework.web.bind.annotation.RestController;
7 |
8 | import java.util.List;
9 |
10 | @RestController
11 | public class WaiterServiceController {
12 | @Autowired
13 | private TakeOutOrderRepository orderRepository;
14 |
15 | @RequestMapping("/orders/{id}")
16 | public TakeOutOrder getOrder(@PathVariable("id") Long id) {
17 | return id == null ? null : orderRepository.getOne(id);
18 | }
19 |
20 | @RequestMapping("/orders")
21 | public List getAllOrder() {
22 | return orderRepository.findAll();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/section-01/waiter-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | management.endpoints.web.exposure.include=*
2 | spring.output.ansi.enabled=ALWAYS
--------------------------------------------------------------------------------
/section-01/waiter-service/src/test/java/takeout/waiterservice/WaiterServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class WaiterServiceApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-02/README.md:
--------------------------------------------------------------------------------
1 | # Section 02
2 |
3 | 相对Section 01,主要有以下变化:
4 |
5 | 1. 重构服务,调整包结构,按功能划分
6 | 2. 增加支付相关接口
7 | 3. 演示了Spring MVC的一些功能
8 |
--------------------------------------------------------------------------------
/section-02/waiter-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-02/waiter-service/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | takeout
7 | waiter-service
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | waiter-service
12 | a simple microservice demo
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.0.5.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 |
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter-actuator
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-starter-data-jpa
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter-web
39 |
40 |
41 |
42 | com.h2database
43 | h2
44 | runtime
45 |
46 |
47 | org.projectlombok
48 | lombok
49 | true
50 |
51 |
52 | org.springframework.boot
53 | spring-boot-starter-test
54 | test
55 |
56 |
57 |
58 |
59 |
60 |
61 | org.springframework.boot
62 | spring-boot-maven-plugin
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/section-02/waiter-service/src/main/java/takeout/waiterservice/DataInitializerRunner.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.boot.ApplicationArguments;
5 | import org.springframework.boot.ApplicationRunner;
6 | import org.springframework.stereotype.Component;
7 | import takeout.waiterservice.model.TakeOutOrder;
8 | import takeout.waiterservice.repository.TakeOutOrderRepository;
9 |
10 | import java.util.Date;
11 |
12 | @Component
13 | public class DataInitializerRunner implements ApplicationRunner {
14 | @Autowired
15 | private TakeOutOrderRepository orderRepository;
16 |
17 | @Override
18 | public void run(ApplicationArguments args) throws Exception {
19 | TakeOutOrder order = TakeOutOrder.builder()
20 | .customer("Steve")
21 | .waiter("Tony")
22 | .items("Hamburger")
23 | .price(1000L)
24 | .state("I")
25 | .createTime(new Date())
26 | .modifyTime(new Date()).build();
27 | orderRepository.save(order);
28 |
29 | order = TakeOutOrder.builder()
30 | .customer("Bruce")
31 | .waiter("Tony")
32 | .items("Sandwich")
33 | .price(1000L)
34 | .state("I")
35 | .createTime(new Date())
36 | .modifyTime(new Date()).build();
37 | orderRepository.save(order);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/section-02/waiter-service/src/main/java/takeout/waiterservice/WaiterServiceApplication.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class WaiterServiceApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(WaiterServiceApplication.class, args);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/section-02/waiter-service/src/main/java/takeout/waiterservice/controller/ExceptionControllerAdvice.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.http.HttpStatus;
4 | import org.springframework.web.bind.annotation.ControllerAdvice;
5 | import org.springframework.web.bind.annotation.ExceptionHandler;
6 | import org.springframework.web.bind.annotation.ResponseStatus;
7 |
8 | import javax.persistence.EntityNotFoundException;
9 | import java.util.Collections;
10 | import java.util.Map;
11 |
12 | @ControllerAdvice
13 | public class ExceptionControllerAdvice {
14 | @ExceptionHandler(EntityNotFoundException.class)
15 | @ResponseStatus(HttpStatus.NOT_FOUND)
16 | public Map entityNotFound(EntityNotFoundException e) {
17 | return Collections.singletonMap("message", e.getMessage());
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/section-02/waiter-service/src/main/java/takeout/waiterservice/controller/OrderController.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.web.bind.annotation.DeleteMapping;
6 | import org.springframework.web.bind.annotation.GetMapping;
7 | import org.springframework.web.bind.annotation.PathVariable;
8 | import org.springframework.web.bind.annotation.PostMapping;
9 | import org.springframework.web.bind.annotation.RequestBody;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.ResponseStatus;
12 | import org.springframework.web.bind.annotation.RestController;
13 | import takeout.waiterservice.model.TakeOutOrder;
14 | import takeout.waiterservice.service.OrderService;
15 |
16 | import java.util.List;
17 |
18 | @RestController
19 | @RequestMapping("/orders")
20 | public class OrderController {
21 | @Autowired
22 | private OrderService orderService;
23 |
24 | @GetMapping("/{id}")
25 | public TakeOutOrder getOrder(@PathVariable Long id) {
26 | return orderService.getOrder(id);
27 | }
28 |
29 | @DeleteMapping("/{id}")
30 | public List deleteOrder(@PathVariable Long id) {
31 | orderService.deleteOrder(id);
32 | return orderService.getAllOrders();
33 | }
34 |
35 | @PostMapping
36 | @ResponseStatus(HttpStatus.CREATED)
37 | public TakeOutOrder createOrder(@RequestBody TakeOutOrder order) {
38 | return orderService.createOrder(order);
39 | }
40 |
41 | @GetMapping
42 | public List getAllOrder() {
43 | return orderService.getAllOrders();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/section-02/waiter-service/src/main/java/takeout/waiterservice/controller/PaymentController.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.web.bind.annotation.PathVariable;
6 | import org.springframework.web.bind.annotation.RequestBody;
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 | import org.springframework.web.bind.annotation.RestController;
11 | import takeout.waiterservice.model.Payment;
12 | import takeout.waiterservice.service.PaymentService;
13 |
14 | @RestController
15 | @RequestMapping("/orders/{id}/payment")
16 | public class PaymentController {
17 | @Autowired
18 | private PaymentService paymentService;
19 |
20 | @RequestMapping(method = RequestMethod.POST)
21 | @ResponseStatus(HttpStatus.CREATED)
22 | public Payment createPayment(@PathVariable Long id) {
23 | return paymentService.createPayment(id);
24 | }
25 |
26 | @RequestMapping(method = RequestMethod.GET)
27 | public Payment getPayment(@PathVariable Long id) {
28 | return paymentService.getPayment(id);
29 | }
30 |
31 | @RequestMapping(method = RequestMethod.PUT)
32 | public Payment updatePayment(@PathVariable Long id, @RequestBody Payment payment) {
33 | return paymentService.updatePayment(id, payment);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/section-02/waiter-service/src/main/java/takeout/waiterservice/model/Payment.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.persistence.Column;
10 | import javax.persistence.Entity;
11 | import javax.persistence.GeneratedValue;
12 | import javax.persistence.Id;
13 | import javax.xml.bind.annotation.XmlRootElement;
14 | import java.util.Date;
15 |
16 | @Entity
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @XmlRootElement
22 | public class Payment {
23 | @Id
24 | @GeneratedValue
25 | private Long id;
26 | @Column(updatable = false)
27 | private Long orderId;
28 | private Long price;
29 | private String state;
30 | @Column(updatable = false)
31 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
32 | private Date createTime;
33 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
34 | private Date modifyTime;
35 | }
36 |
--------------------------------------------------------------------------------
/section-02/waiter-service/src/main/java/takeout/waiterservice/model/TakeOutOrder.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | import javax.persistence.Column;
11 | import javax.persistence.Entity;
12 | import javax.persistence.GeneratedValue;
13 | import javax.persistence.Id;
14 | import javax.xml.bind.annotation.XmlRootElement;
15 | import java.util.Date;
16 |
17 | @Data
18 | @NoArgsConstructor
19 | @AllArgsConstructor
20 | @Builder
21 | @JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler", "fieldHandler"})
22 | @Entity
23 | @XmlRootElement
24 | public class TakeOutOrder {
25 | @Id
26 | @GeneratedValue
27 | private Long id;
28 | private String items;
29 | private String customer;
30 | private String waiter;
31 | private Long price;
32 | private String state;
33 | @Column(updatable = false)
34 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
35 | private Date createTime;
36 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
37 | private Date modifyTime;
38 | }
39 |
--------------------------------------------------------------------------------
/section-02/waiter-service/src/main/java/takeout/waiterservice/repository/PaymentRepository.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import takeout.waiterservice.model.Payment;
5 |
6 | import java.util.Optional;
7 |
8 | public interface PaymentRepository extends JpaRepository {
9 | Optional findByOrderId(Long orderId);
10 | }
11 |
--------------------------------------------------------------------------------
/section-02/waiter-service/src/main/java/takeout/waiterservice/repository/TakeOutOrderRepository.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import takeout.waiterservice.model.TakeOutOrder;
5 |
6 | import java.util.List;
7 |
8 | public interface TakeOutOrderRepository extends JpaRepository {
9 | List findByCustomerOrderById(String customer);
10 | }
11 |
--------------------------------------------------------------------------------
/section-02/waiter-service/src/main/java/takeout/waiterservice/service/OrderService.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.service;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.stereotype.Service;
5 | import takeout.waiterservice.model.TakeOutOrder;
6 | import takeout.waiterservice.repository.TakeOutOrderRepository;
7 |
8 | import javax.persistence.EntityNotFoundException;
9 | import java.util.Date;
10 | import java.util.List;
11 |
12 | @Service
13 | public class OrderService {
14 | @Autowired
15 | private TakeOutOrderRepository orderRepository;
16 |
17 | public List getAllOrders() {
18 | return orderRepository.findAll();
19 | }
20 |
21 | public TakeOutOrder getOrder(Long id) {
22 | return id == null ? null : orderRepository.findById(id)
23 | .orElseThrow(() -> new EntityNotFoundException("Order " + id + " is NOT found."));
24 | }
25 |
26 | public void deleteOrder(Long id) {
27 | orderRepository.delete(
28 | orderRepository.findById(id)
29 | .orElseThrow(() -> new EntityNotFoundException("Order " + id + " is NOT found."))
30 | );
31 | }
32 |
33 | public TakeOutOrder createOrder(TakeOutOrder order) {
34 | if (order != null) {
35 | order.setId(null);
36 | order.setWaiter("Tony");
37 | order.setState("I");
38 | order.setCreateTime(new Date());
39 | order.setModifyTime(new Date());
40 | orderRepository.save(order);
41 | }
42 | return order;
43 | }
44 |
45 | public void payOrder(Long id) {
46 | TakeOutOrder order = orderRepository.getOne(id);
47 | order.setState("P");
48 | order.setModifyTime(new Date());
49 | orderRepository.save(order);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/section-02/waiter-service/src/main/java/takeout/waiterservice/service/PaymentService.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.service;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.stereotype.Service;
5 | import takeout.waiterservice.model.Payment;
6 | import takeout.waiterservice.model.TakeOutOrder;
7 | import takeout.waiterservice.repository.PaymentRepository;
8 |
9 | import javax.persistence.EntityNotFoundException;
10 | import javax.transaction.Transactional;
11 | import java.util.Date;
12 | import java.util.Optional;
13 |
14 | @Service
15 | @Transactional
16 | public class PaymentService {
17 | @Autowired
18 | private OrderService orderService;
19 | @Autowired
20 | private PaymentRepository paymentRepository;
21 |
22 | public Payment getPayment(Long orderId) {
23 | return paymentRepository.findByOrderId(orderId)
24 | .orElseThrow(() -> new EntityNotFoundException("Order " + orderId + " has NO payment!"));
25 | }
26 |
27 | public Payment createPayment(Long orderId) {
28 | Optional savedPayment = paymentRepository.findByOrderId(orderId);
29 | if (savedPayment.isPresent()) {
30 | return savedPayment.get();
31 | }
32 |
33 | TakeOutOrder order = orderService.getOrder(orderId);
34 | if (order == null) {
35 | throw new EntityNotFoundException("Order " + orderId + " is NOT Found!");
36 | }
37 | Payment payment = Payment.builder()
38 | .orderId(orderId)
39 | .price(order.getPrice())
40 | .state("I")
41 | .createTime(new Date())
42 | .modifyTime(new Date()).build();
43 | return paymentRepository.save(payment);
44 | }
45 |
46 | public Payment updatePayment(Long orderId, Payment payment) {
47 | Payment savedPayment = paymentRepository.findByOrderId(orderId)
48 | .orElseThrow(() -> new EntityNotFoundException("Order " + orderId + " has NO payment!"));
49 |
50 | if ("S".equalsIgnoreCase(payment.getState())) {
51 | orderService.payOrder(orderId);
52 | }
53 | savedPayment.setState(payment.getState());
54 | savedPayment.setModifyTime(new Date());
55 | return paymentRepository.save(savedPayment);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/section-02/waiter-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.output.ansi.enabled=ALWAYS
--------------------------------------------------------------------------------
/section-02/waiter-service/src/test/java/takeout/waiterservice/WaiterServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class WaiterServiceApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-03/README.md:
--------------------------------------------------------------------------------
1 | # Section 03
2 |
3 | 为waiter-service的REST服务编写了一个客户端,主要演示如下功能:
4 |
5 | 1. Spring RestTemplate的基本用法
6 | 2. 各种HTTP Method的调用方法
7 |
--------------------------------------------------------------------------------
/section-03/customer-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-03/customer-service/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | takeout
7 | customer-service
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | customer-service
12 | a simple microservice demo
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.0.5.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 |
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter-web
31 |
32 |
33 |
34 | org.projectlombok
35 | lombok
36 | true
37 |
38 |
39 | org.springframework.boot
40 | spring-boot-starter-test
41 | test
42 |
43 |
44 |
45 |
46 |
47 |
48 | org.springframework.boot
49 | spring-boot-maven-plugin
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/section-03/customer-service/src/main/java/takeout/customerservice/CustomerServiceApplication.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.context.annotation.Bean;
6 | import org.springframework.web.client.RestTemplate;
7 |
8 | @SpringBootApplication
9 | public class CustomerServiceApplication {
10 |
11 | public static void main(String[] args) {
12 | SpringApplication.run(CustomerServiceApplication.class, args);
13 | }
14 |
15 | @Bean
16 | public RestTemplate restTemplate() {
17 | return new RestTemplate();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/section-03/customer-service/src/main/java/takeout/customerservice/model/Order.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice.model;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @NoArgsConstructor
10 | @AllArgsConstructor
11 | @Builder
12 | public class Order {
13 | private Long id;
14 | private String items;
15 | private String customer;
16 | private String waiter;
17 | private Long price;
18 | private String state;
19 | }
20 |
--------------------------------------------------------------------------------
/section-03/customer-service/src/main/java/takeout/customerservice/model/Payment.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice.model;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @AllArgsConstructor
10 | @NoArgsConstructor
11 | @Builder
12 | public class Payment {
13 | private Long id;
14 | private Long orderId;
15 | private Long price;
16 | private String state;
17 | }
18 |
--------------------------------------------------------------------------------
/section-03/customer-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | customer.name=Natasha
2 | waiter.url=http://127.0.0.1:8080
3 |
4 | server.port=7080
5 | spring.output.ansi.enabled=ALWAYS
6 |
--------------------------------------------------------------------------------
/section-03/customer-service/src/test/java/takeout/customerservice/CustomerServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class CustomerServiceApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-04/README.md:
--------------------------------------------------------------------------------
1 | # Section 04
2 |
3 | 用Spring Data REST重构了Section 02和Section 03的代码:
4 |
5 | 1. 以HATEOS的方式暴露了TakeOutOrder资源
6 | 2. 客户端通过REL自动发现URI资源并发起调用
7 |
8 |
--------------------------------------------------------------------------------
/section-04/customer-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-04/customer-service/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | takeout
7 | customer-service
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | customer-service
12 | a simple microservice demo
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.0.5.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 |
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter-web
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-starter-data-rest
35 |
36 |
37 |
38 | org.projectlombok
39 | lombok
40 | true
41 |
42 |
43 | org.springframework.boot
44 | spring-boot-starter-test
45 | test
46 |
47 |
48 |
49 |
50 |
51 |
52 | org.springframework.boot
53 | spring-boot-maven-plugin
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/section-04/customer-service/src/main/java/takeout/customerservice/CustomerServiceApplication.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice;
2 |
3 | import com.fasterxml.jackson.databind.DeserializationFeature;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import org.springframework.boot.SpringApplication;
6 | import org.springframework.boot.autoconfigure.SpringBootApplication;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.hateoas.hal.Jackson2HalModule;
9 | import org.springframework.http.MediaType;
10 | import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
11 | import org.springframework.web.client.RestTemplate;
12 |
13 | import java.util.Arrays;
14 |
15 | @SpringBootApplication
16 | public class CustomerServiceApplication {
17 |
18 | public static void main(String[] args) {
19 | SpringApplication.run(CustomerServiceApplication.class, args);
20 | }
21 |
22 | @Bean
23 | public RestTemplate restTemplate() {
24 | ObjectMapper mapper = new ObjectMapper();
25 | mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
26 | mapper.registerModule(new Jackson2HalModule());
27 |
28 | MappingJackson2HttpMessageConverter converter =
29 | new MappingJackson2HttpMessageConverter();
30 | converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json"));
31 | converter.setObjectMapper(mapper);
32 |
33 | return new RestTemplate(Arrays.asList(converter));
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/section-04/customer-service/src/main/java/takeout/customerservice/model/TakeOutOrder.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice.model;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @NoArgsConstructor
10 | @AllArgsConstructor
11 | @Builder
12 | public class TakeOutOrder {
13 | private Long id;
14 | private String items;
15 | private String customer;
16 | private String waiter;
17 | private Long price;
18 | private String state;
19 | }
20 |
--------------------------------------------------------------------------------
/section-04/customer-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | customer.name=Natasha
2 | waiter.url=http://127.0.0.1:8080
3 |
4 | server.port=7080
5 | spring.output.ansi.enabled=ALWAYS
6 |
--------------------------------------------------------------------------------
/section-04/customer-service/src/test/java/takeout/customerservice/CustomerServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class CustomerServiceApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-04/waiter-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-04/waiter-service/src/main/java/takeout/waiterservice/DataInitializerRunner.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.boot.ApplicationArguments;
5 | import org.springframework.boot.ApplicationRunner;
6 | import org.springframework.stereotype.Component;
7 | import takeout.waiterservice.model.TakeOutOrder;
8 | import takeout.waiterservice.repository.TakeOutOrderRepository;
9 |
10 | import java.util.Date;
11 |
12 | @Component
13 | public class DataInitializerRunner implements ApplicationRunner {
14 | @Autowired
15 | private TakeOutOrderRepository orderRepository;
16 |
17 | @Override
18 | public void run(ApplicationArguments args) throws Exception {
19 | TakeOutOrder order = TakeOutOrder.builder()
20 | .customer("Steve")
21 | .waiter("Tony")
22 | .items("Hamburger")
23 | .price(1000L)
24 | .state("I")
25 | .createTime(new Date())
26 | .modifyTime(new Date()).build();
27 | orderRepository.save(order);
28 |
29 | order = TakeOutOrder.builder()
30 | .customer("Bruce")
31 | .waiter("Tony")
32 | .items("Sandwich")
33 | .price(1000L)
34 | .state("I")
35 | .createTime(new Date())
36 | .modifyTime(new Date()).build();
37 | orderRepository.save(order);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/section-04/waiter-service/src/main/java/takeout/waiterservice/WaiterServiceApplication.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class WaiterServiceApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(WaiterServiceApplication.class, args);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/section-04/waiter-service/src/main/java/takeout/waiterservice/controller/ExceptionControllerAdvice.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.http.HttpStatus;
4 | import org.springframework.web.bind.annotation.ControllerAdvice;
5 | import org.springframework.web.bind.annotation.ExceptionHandler;
6 | import org.springframework.web.bind.annotation.ResponseStatus;
7 |
8 | import javax.persistence.EntityNotFoundException;
9 | import java.util.Collections;
10 | import java.util.Map;
11 |
12 | @ControllerAdvice
13 | public class ExceptionControllerAdvice {
14 | @ExceptionHandler(EntityNotFoundException.class)
15 | @ResponseStatus(HttpStatus.NOT_FOUND)
16 | public Map entityNotFound(EntityNotFoundException e) {
17 | return Collections.singletonMap("message", e.getMessage());
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/section-04/waiter-service/src/main/java/takeout/waiterservice/controller/OrderController.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.web.bind.annotation.DeleteMapping;
6 | import org.springframework.web.bind.annotation.GetMapping;
7 | import org.springframework.web.bind.annotation.PathVariable;
8 | import org.springframework.web.bind.annotation.PostMapping;
9 | import org.springframework.web.bind.annotation.RequestBody;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.ResponseStatus;
12 | import org.springframework.web.bind.annotation.RestController;
13 | import takeout.waiterservice.model.TakeOutOrder;
14 | import takeout.waiterservice.service.OrderService;
15 |
16 | import java.util.List;
17 |
18 | @RestController
19 | @RequestMapping("/orders")
20 | public class OrderController {
21 | @Autowired
22 | private OrderService orderService;
23 |
24 | @GetMapping("/{id}")
25 | public TakeOutOrder getOrder(@PathVariable Long id) {
26 | return orderService.getOrder(id);
27 | }
28 |
29 | @DeleteMapping("/{id}")
30 | public List deleteOrder(@PathVariable Long id) {
31 | orderService.deleteOrder(id);
32 | return orderService.getAllOrders();
33 | }
34 |
35 | @PostMapping
36 | @ResponseStatus(HttpStatus.CREATED)
37 | public TakeOutOrder createOrder(@RequestBody TakeOutOrder order) {
38 | return orderService.createOrder(order);
39 | }
40 |
41 | @GetMapping
42 | public List getAllOrder() {
43 | return orderService.getAllOrders();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/section-04/waiter-service/src/main/java/takeout/waiterservice/controller/PaymentController.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.web.bind.annotation.PathVariable;
6 | import org.springframework.web.bind.annotation.RequestBody;
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 | import org.springframework.web.bind.annotation.RestController;
11 | import takeout.waiterservice.model.Payment;
12 | import takeout.waiterservice.service.PaymentService;
13 |
14 | @RestController
15 | @RequestMapping("/orders/{id}/payment")
16 | public class PaymentController {
17 | @Autowired
18 | private PaymentService paymentService;
19 |
20 | @RequestMapping(method = RequestMethod.POST)
21 | @ResponseStatus(HttpStatus.CREATED)
22 | public Payment createPayment(@PathVariable Long id) {
23 | return paymentService.createPayment(id);
24 | }
25 |
26 | @RequestMapping(method = RequestMethod.GET)
27 | public Payment getPayment(@PathVariable Long id) {
28 | return paymentService.getPayment(id);
29 | }
30 |
31 | @RequestMapping(method = RequestMethod.PUT)
32 | public Payment updatePayment(@PathVariable Long id, @RequestBody Payment payment) {
33 | return paymentService.updatePayment(id, payment);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/section-04/waiter-service/src/main/java/takeout/waiterservice/model/Payment.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.persistence.Column;
10 | import javax.persistence.Entity;
11 | import javax.persistence.GeneratedValue;
12 | import javax.persistence.Id;
13 | import javax.xml.bind.annotation.XmlRootElement;
14 | import java.util.Date;
15 |
16 | @Entity
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @XmlRootElement
22 | public class Payment {
23 | @Id
24 | @GeneratedValue
25 | private Long id;
26 | @Column(updatable = false)
27 | private Long orderId;
28 | private Long price;
29 | private String state;
30 | @Column(updatable = false)
31 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
32 | private Date createTime;
33 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
34 | private Date modifyTime;
35 | }
36 |
--------------------------------------------------------------------------------
/section-04/waiter-service/src/main/java/takeout/waiterservice/model/TakeOutOrder.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | import javax.persistence.Column;
11 | import javax.persistence.Entity;
12 | import javax.persistence.GeneratedValue;
13 | import javax.persistence.Id;
14 | import javax.xml.bind.annotation.XmlRootElement;
15 | import java.util.Date;
16 |
17 | @Data
18 | @NoArgsConstructor
19 | @AllArgsConstructor
20 | @Builder
21 | @JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler", "fieldHandler"})
22 | @Entity
23 | @XmlRootElement
24 | public class TakeOutOrder {
25 | @Id
26 | @GeneratedValue
27 | private Long id;
28 | private String items;
29 | private String customer;
30 | private String waiter;
31 | private Long price;
32 | private String state;
33 | @Column(updatable = false)
34 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
35 | private Date createTime;
36 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
37 | private Date modifyTime;
38 | }
39 |
--------------------------------------------------------------------------------
/section-04/waiter-service/src/main/java/takeout/waiterservice/repository/PaymentRepository.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import org.springframework.data.repository.query.Param;
5 | import org.springframework.data.rest.core.annotation.RepositoryRestResource;
6 | import takeout.waiterservice.model.Payment;
7 |
8 | import java.util.Optional;
9 |
10 | @RepositoryRestResource
11 | public interface PaymentRepository extends JpaRepository {
12 | Optional findByOrderId(@Param("orderId") Long orderId);
13 | }
14 |
--------------------------------------------------------------------------------
/section-04/waiter-service/src/main/java/takeout/waiterservice/repository/TakeOutOrderRepository.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import org.springframework.data.repository.query.Param;
5 | import takeout.waiterservice.model.TakeOutOrder;
6 |
7 | import java.util.List;
8 |
9 | public interface TakeOutOrderRepository extends JpaRepository {
10 | List findByCustomerOrderById(@Param("customer") String customer);
11 | }
12 |
--------------------------------------------------------------------------------
/section-04/waiter-service/src/main/java/takeout/waiterservice/service/OrderService.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.service;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.stereotype.Service;
5 | import takeout.waiterservice.model.TakeOutOrder;
6 | import takeout.waiterservice.repository.TakeOutOrderRepository;
7 |
8 | import javax.persistence.EntityNotFoundException;
9 | import java.util.Date;
10 | import java.util.List;
11 |
12 | @Service
13 | public class OrderService {
14 | @Autowired
15 | private TakeOutOrderRepository orderRepository;
16 |
17 | public List getAllOrders() {
18 | return orderRepository.findAll();
19 | }
20 |
21 | public TakeOutOrder getOrder(Long id) {
22 | return id == null ? null : orderRepository.findById(id)
23 | .orElseThrow(() -> new EntityNotFoundException("Order " + id + " is NOT found."));
24 | }
25 |
26 | public void deleteOrder(Long id) {
27 | orderRepository.delete(
28 | orderRepository.findById(id)
29 | .orElseThrow(() -> new EntityNotFoundException("Order " + id + " is NOT found."))
30 | );
31 | }
32 |
33 | public TakeOutOrder createOrder(TakeOutOrder order) {
34 | if (order != null) {
35 | order.setId(null);
36 | order.setWaiter("Tony");
37 | order.setState("I");
38 | order.setCreateTime(new Date());
39 | order.setModifyTime(new Date());
40 | orderRepository.save(order);
41 | }
42 | return order;
43 | }
44 |
45 | public void payOrder(Long id) {
46 | TakeOutOrder order = orderRepository.getOne(id);
47 | order.setState("P");
48 | order.setModifyTime(new Date());
49 | orderRepository.save(order);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/section-04/waiter-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.output.ansi.enabled=ALWAYS
--------------------------------------------------------------------------------
/section-04/waiter-service/src/test/java/takeout/waiterservice/WaiterServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class WaiterServiceApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-05/README.md:
--------------------------------------------------------------------------------
1 | # Section 05
2 |
3 | 用Spring Cloud Netflix重构Section 02和Section 03的代码:
4 |
5 | 1. 使用Eureka作为服务注册中心
6 | 2. customer-service使用注册中心获取waiter-service的地址
7 |
8 |
9 |
--------------------------------------------------------------------------------
/section-05/customer-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-05/customer-service/src/main/java/takeout/customerservice/CustomerServiceApplication.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
6 | import org.springframework.cloud.client.loadbalancer.LoadBalanced;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.web.client.RestTemplate;
9 |
10 | @SpringBootApplication
11 | @EnableDiscoveryClient
12 | public class CustomerServiceApplication {
13 |
14 | public static void main(String[] args) {
15 | SpringApplication.run(CustomerServiceApplication.class, args);
16 | }
17 |
18 | @Bean
19 | @LoadBalanced
20 | public RestTemplate restTemplate() {
21 | return new RestTemplate();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/section-05/customer-service/src/main/java/takeout/customerservice/model/Order.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice.model;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @NoArgsConstructor
10 | @AllArgsConstructor
11 | @Builder
12 | public class Order {
13 | private Long id;
14 | private String items;
15 | private String customer;
16 | private String waiter;
17 | private Long price;
18 | private String state;
19 | }
20 |
--------------------------------------------------------------------------------
/section-05/customer-service/src/main/java/takeout/customerservice/model/Payment.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice.model;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @AllArgsConstructor
10 | @NoArgsConstructor
11 | @Builder
12 | public class Payment {
13 | private Long id;
14 | private Long orderId;
15 | private Long price;
16 | private String state;
17 | }
18 |
--------------------------------------------------------------------------------
/section-05/customer-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | customer.name=Natasha
2 | waiter.url=http://waiter-service
3 |
4 | server.port=7080
5 | spring.output.ansi.enabled=ALWAYS
6 |
--------------------------------------------------------------------------------
/section-05/customer-service/src/main/resources/bootstrap.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=customer-service
--------------------------------------------------------------------------------
/section-05/customer-service/src/test/java/takeout/customerservice/CustomerServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class CustomerServiceApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-05/eureka-server/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-05/eureka-server/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | takeout
7 | eureka-server
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | eureka-server
12 | a simple eureka server
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.0.5.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 | Finchley.SR1
26 |
27 |
28 |
29 |
30 | org.springframework.cloud
31 | spring-cloud-starter-netflix-eureka-server
32 |
33 |
34 |
35 | org.springframework.boot
36 | spring-boot-starter-test
37 | test
38 |
39 |
40 |
41 |
42 |
43 |
44 | org.springframework.cloud
45 | spring-cloud-dependencies
46 | ${spring-cloud.version}
47 | pom
48 | import
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | org.springframework.boot
57 | spring-boot-maven-plugin
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/section-05/eureka-server/src/main/java/takeout/eurekaserver/EurekaServerApplication.java:
--------------------------------------------------------------------------------
1 | package takeout.eurekaserver;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
6 |
7 | @SpringBootApplication
8 | @EnableEurekaServer
9 | public class EurekaServerApplication {
10 |
11 | public static void main(String[] args) {
12 | SpringApplication.run(EurekaServerApplication.class, args);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/section-05/eureka-server/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | server.port=8761
2 |
3 | eureka.client.register-with-eureka=false
4 | eureka.client.fetch-registry=false
5 |
--------------------------------------------------------------------------------
/section-05/eureka-server/src/test/java/takeout/eurekaserver/EurekaServerApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.eurekaserver;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class EurekaServerApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-05/waiter-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-05/waiter-service/src/main/java/takeout/waiterservice/DataInitializerRunner.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.boot.ApplicationArguments;
5 | import org.springframework.boot.ApplicationRunner;
6 | import org.springframework.stereotype.Component;
7 | import takeout.waiterservice.model.TakeOutOrder;
8 | import takeout.waiterservice.repository.TakeOutOrderRepository;
9 |
10 | import java.util.Date;
11 |
12 | @Component
13 | public class DataInitializerRunner implements ApplicationRunner {
14 | @Autowired
15 | private TakeOutOrderRepository orderRepository;
16 |
17 | @Override
18 | public void run(ApplicationArguments args) throws Exception {
19 | TakeOutOrder order = TakeOutOrder.builder()
20 | .customer("Steve")
21 | .waiter("Tony")
22 | .items("Hamburger")
23 | .price(1000L)
24 | .state("I")
25 | .createTime(new Date())
26 | .modifyTime(new Date()).build();
27 | orderRepository.save(order);
28 |
29 | order = TakeOutOrder.builder()
30 | .customer("Bruce")
31 | .waiter("Tony")
32 | .items("Sandwich")
33 | .price(1000L)
34 | .state("I")
35 | .createTime(new Date())
36 | .modifyTime(new Date()).build();
37 | orderRepository.save(order);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/section-05/waiter-service/src/main/java/takeout/waiterservice/WaiterServiceApplication.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
6 |
7 | @SpringBootApplication
8 | @EnableDiscoveryClient
9 | public class WaiterServiceApplication {
10 |
11 | public static void main(String[] args) {
12 | SpringApplication.run(WaiterServiceApplication.class, args);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/section-05/waiter-service/src/main/java/takeout/waiterservice/controller/ExceptionControllerAdvice.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.http.HttpStatus;
4 | import org.springframework.web.bind.annotation.ControllerAdvice;
5 | import org.springframework.web.bind.annotation.ExceptionHandler;
6 | import org.springframework.web.bind.annotation.ResponseStatus;
7 |
8 | import javax.persistence.EntityNotFoundException;
9 | import java.util.Collections;
10 | import java.util.Map;
11 |
12 | @ControllerAdvice
13 | public class ExceptionControllerAdvice {
14 | @ExceptionHandler(EntityNotFoundException.class)
15 | @ResponseStatus(HttpStatus.NOT_FOUND)
16 | public Map entityNotFound(EntityNotFoundException e) {
17 | return Collections.singletonMap("message", e.getMessage());
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/section-05/waiter-service/src/main/java/takeout/waiterservice/controller/OrderController.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.web.bind.annotation.DeleteMapping;
6 | import org.springframework.web.bind.annotation.GetMapping;
7 | import org.springframework.web.bind.annotation.PathVariable;
8 | import org.springframework.web.bind.annotation.PostMapping;
9 | import org.springframework.web.bind.annotation.RequestBody;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.ResponseStatus;
12 | import org.springframework.web.bind.annotation.RestController;
13 | import takeout.waiterservice.model.TakeOutOrder;
14 | import takeout.waiterservice.service.OrderService;
15 |
16 | import java.util.List;
17 |
18 | @RestController
19 | @RequestMapping("/orders")
20 | public class OrderController {
21 | @Autowired
22 | private OrderService orderService;
23 |
24 | @GetMapping("/{id}")
25 | public TakeOutOrder getOrder(@PathVariable Long id) {
26 | return orderService.getOrder(id);
27 | }
28 |
29 | @DeleteMapping("/{id}")
30 | public List deleteOrder(@PathVariable Long id) {
31 | orderService.deleteOrder(id);
32 | return orderService.getAllOrders();
33 | }
34 |
35 | @PostMapping
36 | @ResponseStatus(HttpStatus.CREATED)
37 | public TakeOutOrder createOrder(@RequestBody TakeOutOrder order) {
38 | return orderService.createOrder(order);
39 | }
40 |
41 | @GetMapping
42 | public List getAllOrder() {
43 | return orderService.getAllOrders();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/section-05/waiter-service/src/main/java/takeout/waiterservice/controller/PaymentController.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.web.bind.annotation.PathVariable;
6 | import org.springframework.web.bind.annotation.RequestBody;
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 | import org.springframework.web.bind.annotation.RestController;
11 | import takeout.waiterservice.model.Payment;
12 | import takeout.waiterservice.service.PaymentService;
13 |
14 | @RestController
15 | @RequestMapping("/orders/{id}/payment")
16 | public class PaymentController {
17 | @Autowired
18 | private PaymentService paymentService;
19 |
20 | @RequestMapping(method = RequestMethod.POST)
21 | @ResponseStatus(HttpStatus.CREATED)
22 | public Payment createPayment(@PathVariable Long id) {
23 | return paymentService.createPayment(id);
24 | }
25 |
26 | @RequestMapping(method = RequestMethod.GET)
27 | public Payment getPayment(@PathVariable Long id) {
28 | return paymentService.getPayment(id);
29 | }
30 |
31 | @RequestMapping(method = RequestMethod.PUT)
32 | public Payment updatePayment(@PathVariable Long id, @RequestBody Payment payment) {
33 | return paymentService.updatePayment(id, payment);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/section-05/waiter-service/src/main/java/takeout/waiterservice/model/Payment.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.persistence.Column;
10 | import javax.persistence.Entity;
11 | import javax.persistence.GeneratedValue;
12 | import javax.persistence.Id;
13 | import javax.xml.bind.annotation.XmlRootElement;
14 | import java.util.Date;
15 |
16 | @Entity
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @XmlRootElement
22 | public class Payment {
23 | @Id
24 | @GeneratedValue
25 | private Long id;
26 | @Column(updatable = false)
27 | private Long orderId;
28 | private Long price;
29 | private String state;
30 | @Column(updatable = false)
31 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
32 | private Date createTime;
33 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
34 | private Date modifyTime;
35 | }
36 |
--------------------------------------------------------------------------------
/section-05/waiter-service/src/main/java/takeout/waiterservice/model/TakeOutOrder.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | import javax.persistence.Column;
11 | import javax.persistence.Entity;
12 | import javax.persistence.GeneratedValue;
13 | import javax.persistence.Id;
14 | import javax.xml.bind.annotation.XmlRootElement;
15 | import java.util.Date;
16 |
17 | @Data
18 | @NoArgsConstructor
19 | @AllArgsConstructor
20 | @Builder
21 | @JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler", "fieldHandler"})
22 | @Entity
23 | @XmlRootElement
24 | public class TakeOutOrder {
25 | @Id
26 | @GeneratedValue
27 | private Long id;
28 | private String items;
29 | private String customer;
30 | private String waiter;
31 | private Long price;
32 | private String state;
33 | @Column(updatable = false)
34 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
35 | private Date createTime;
36 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
37 | private Date modifyTime;
38 | }
39 |
--------------------------------------------------------------------------------
/section-05/waiter-service/src/main/java/takeout/waiterservice/repository/PaymentRepository.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import takeout.waiterservice.model.Payment;
5 |
6 | import java.util.Optional;
7 |
8 | public interface PaymentRepository extends JpaRepository {
9 | Optional findByOrderId(Long orderId);
10 | }
11 |
--------------------------------------------------------------------------------
/section-05/waiter-service/src/main/java/takeout/waiterservice/repository/TakeOutOrderRepository.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import takeout.waiterservice.model.TakeOutOrder;
5 |
6 | import java.util.List;
7 |
8 | public interface TakeOutOrderRepository extends JpaRepository {
9 | List findByCustomerOrderById(String customer);
10 | }
11 |
--------------------------------------------------------------------------------
/section-05/waiter-service/src/main/java/takeout/waiterservice/service/OrderService.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.service;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.stereotype.Service;
5 | import takeout.waiterservice.model.TakeOutOrder;
6 | import takeout.waiterservice.repository.TakeOutOrderRepository;
7 |
8 | import javax.persistence.EntityNotFoundException;
9 | import java.util.Date;
10 | import java.util.List;
11 |
12 | @Service
13 | public class OrderService {
14 | @Autowired
15 | private TakeOutOrderRepository orderRepository;
16 |
17 | public List getAllOrders() {
18 | return orderRepository.findAll();
19 | }
20 |
21 | public TakeOutOrder getOrder(Long id) {
22 | return id == null ? null : orderRepository.findById(id)
23 | .orElseThrow(() -> new EntityNotFoundException("Order " + id + " is NOT found."));
24 | }
25 |
26 | public void deleteOrder(Long id) {
27 | orderRepository.delete(
28 | orderRepository.findById(id)
29 | .orElseThrow(() -> new EntityNotFoundException("Order " + id + " is NOT found."))
30 | );
31 | }
32 |
33 | public TakeOutOrder createOrder(TakeOutOrder order) {
34 | if (order != null) {
35 | order.setId(null);
36 | order.setWaiter("Tony");
37 | order.setState("I");
38 | order.setCreateTime(new Date());
39 | order.setModifyTime(new Date());
40 | orderRepository.save(order);
41 | }
42 | return order;
43 | }
44 |
45 | public void payOrder(Long id) {
46 | TakeOutOrder order = orderRepository.getOne(id);
47 | order.setState("P");
48 | order.setModifyTime(new Date());
49 | orderRepository.save(order);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/section-05/waiter-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.output.ansi.enabled=ALWAYS
--------------------------------------------------------------------------------
/section-05/waiter-service/src/main/resources/bootstrap.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=waiter-service
--------------------------------------------------------------------------------
/section-05/waiter-service/src/test/java/takeout/waiterservice/WaiterServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class WaiterServiceApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-06/README.md:
--------------------------------------------------------------------------------
1 | # Section 06
2 |
3 | 用Zookeeper作为服务注册中心,重构Section 05的代码。
4 |
5 | 使用Docker在本地启动一个Zookeeper:
6 |
7 | ```
8 | docker pull zookeeper:3.5
9 | docker run --name zookeeper -p 2181:2181 -d zookeeper:3.5
10 | ```
11 |
--------------------------------------------------------------------------------
/section-06/customer-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-06/customer-service/src/main/java/takeout/customerservice/CustomerServiceApplication.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
6 | import org.springframework.cloud.client.loadbalancer.LoadBalanced;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.web.client.RestTemplate;
9 |
10 | @SpringBootApplication
11 | @EnableDiscoveryClient
12 | public class CustomerServiceApplication {
13 |
14 | public static void main(String[] args) {
15 | SpringApplication.run(CustomerServiceApplication.class, args);
16 | }
17 |
18 | @Bean
19 | @LoadBalanced
20 | public RestTemplate restTemplate() {
21 | return new RestTemplate();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/section-06/customer-service/src/main/java/takeout/customerservice/model/Order.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice.model;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @NoArgsConstructor
10 | @AllArgsConstructor
11 | @Builder
12 | public class Order {
13 | private Long id;
14 | private String items;
15 | private String customer;
16 | private String waiter;
17 | private Long price;
18 | private String state;
19 | }
20 |
--------------------------------------------------------------------------------
/section-06/customer-service/src/main/java/takeout/customerservice/model/Payment.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice.model;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @AllArgsConstructor
10 | @NoArgsConstructor
11 | @Builder
12 | public class Payment {
13 | private Long id;
14 | private Long orderId;
15 | private Long price;
16 | private String state;
17 | }
18 |
--------------------------------------------------------------------------------
/section-06/customer-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | customer.name=Natasha
2 | waiter.url=http://waiter-service
3 |
4 | server.port=7080
5 | spring.output.ansi.enabled=ALWAYS
6 |
--------------------------------------------------------------------------------
/section-06/customer-service/src/main/resources/bootstrap.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=customer-service
--------------------------------------------------------------------------------
/section-06/customer-service/src/test/java/takeout/customerservice/CustomerServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class CustomerServiceApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-06/waiter-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-06/waiter-service/src/main/java/takeout/waiterservice/DataInitializerRunner.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.boot.ApplicationArguments;
5 | import org.springframework.boot.ApplicationRunner;
6 | import org.springframework.stereotype.Component;
7 | import takeout.waiterservice.model.TakeOutOrder;
8 | import takeout.waiterservice.repository.TakeOutOrderRepository;
9 |
10 | import java.util.Date;
11 |
12 | @Component
13 | public class DataInitializerRunner implements ApplicationRunner {
14 | @Autowired
15 | private TakeOutOrderRepository orderRepository;
16 |
17 | @Override
18 | public void run(ApplicationArguments args) throws Exception {
19 | TakeOutOrder order = TakeOutOrder.builder()
20 | .customer("Steve")
21 | .waiter("Tony")
22 | .items("Hamburger")
23 | .price(1000L)
24 | .state("I")
25 | .createTime(new Date())
26 | .modifyTime(new Date()).build();
27 | orderRepository.save(order);
28 |
29 | order = TakeOutOrder.builder()
30 | .customer("Bruce")
31 | .waiter("Tony")
32 | .items("Sandwich")
33 | .price(1000L)
34 | .state("I")
35 | .createTime(new Date())
36 | .modifyTime(new Date()).build();
37 | orderRepository.save(order);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/section-06/waiter-service/src/main/java/takeout/waiterservice/WaiterServiceApplication.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
6 |
7 | @SpringBootApplication
8 | @EnableDiscoveryClient
9 | public class WaiterServiceApplication {
10 |
11 | public static void main(String[] args) {
12 | SpringApplication.run(WaiterServiceApplication.class, args);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/section-06/waiter-service/src/main/java/takeout/waiterservice/controller/ExceptionControllerAdvice.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.http.HttpStatus;
4 | import org.springframework.web.bind.annotation.ControllerAdvice;
5 | import org.springframework.web.bind.annotation.ExceptionHandler;
6 | import org.springframework.web.bind.annotation.ResponseStatus;
7 |
8 | import javax.persistence.EntityNotFoundException;
9 | import java.util.Collections;
10 | import java.util.Map;
11 |
12 | @ControllerAdvice
13 | public class ExceptionControllerAdvice {
14 | @ExceptionHandler(EntityNotFoundException.class)
15 | @ResponseStatus(HttpStatus.NOT_FOUND)
16 | public Map entityNotFound(EntityNotFoundException e) {
17 | return Collections.singletonMap("message", e.getMessage());
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/section-06/waiter-service/src/main/java/takeout/waiterservice/controller/OrderController.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.web.bind.annotation.DeleteMapping;
6 | import org.springframework.web.bind.annotation.GetMapping;
7 | import org.springframework.web.bind.annotation.PathVariable;
8 | import org.springframework.web.bind.annotation.PostMapping;
9 | import org.springframework.web.bind.annotation.RequestBody;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.ResponseStatus;
12 | import org.springframework.web.bind.annotation.RestController;
13 | import takeout.waiterservice.model.TakeOutOrder;
14 | import takeout.waiterservice.service.OrderService;
15 |
16 | import java.util.List;
17 |
18 | @RestController
19 | @RequestMapping("/orders")
20 | public class OrderController {
21 | @Autowired
22 | private OrderService orderService;
23 |
24 | @GetMapping("/{id}")
25 | public TakeOutOrder getOrder(@PathVariable Long id) {
26 | return orderService.getOrder(id);
27 | }
28 |
29 | @DeleteMapping("/{id}")
30 | public List deleteOrder(@PathVariable Long id) {
31 | orderService.deleteOrder(id);
32 | return orderService.getAllOrders();
33 | }
34 |
35 | @PostMapping
36 | @ResponseStatus(HttpStatus.CREATED)
37 | public TakeOutOrder createOrder(@RequestBody TakeOutOrder order) {
38 | return orderService.createOrder(order);
39 | }
40 |
41 | @GetMapping
42 | public List getAllOrder() {
43 | return orderService.getAllOrders();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/section-06/waiter-service/src/main/java/takeout/waiterservice/controller/PaymentController.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.web.bind.annotation.PathVariable;
6 | import org.springframework.web.bind.annotation.RequestBody;
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 | import org.springframework.web.bind.annotation.RestController;
11 | import takeout.waiterservice.model.Payment;
12 | import takeout.waiterservice.service.PaymentService;
13 |
14 | @RestController
15 | @RequestMapping("/orders/{id}/payment")
16 | public class PaymentController {
17 | @Autowired
18 | private PaymentService paymentService;
19 |
20 | @RequestMapping(method = RequestMethod.POST)
21 | @ResponseStatus(HttpStatus.CREATED)
22 | public Payment createPayment(@PathVariable Long id) {
23 | return paymentService.createPayment(id);
24 | }
25 |
26 | @RequestMapping(method = RequestMethod.GET)
27 | public Payment getPayment(@PathVariable Long id) {
28 | return paymentService.getPayment(id);
29 | }
30 |
31 | @RequestMapping(method = RequestMethod.PUT)
32 | public Payment updatePayment(@PathVariable Long id, @RequestBody Payment payment) {
33 | return paymentService.updatePayment(id, payment);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/section-06/waiter-service/src/main/java/takeout/waiterservice/model/Payment.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.persistence.Column;
10 | import javax.persistence.Entity;
11 | import javax.persistence.GeneratedValue;
12 | import javax.persistence.Id;
13 | import javax.xml.bind.annotation.XmlRootElement;
14 | import java.util.Date;
15 |
16 | @Entity
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @XmlRootElement
22 | public class Payment {
23 | @Id
24 | @GeneratedValue
25 | private Long id;
26 | @Column(updatable = false)
27 | private Long orderId;
28 | private Long price;
29 | private String state;
30 | @Column(updatable = false)
31 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
32 | private Date createTime;
33 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
34 | private Date modifyTime;
35 | }
36 |
--------------------------------------------------------------------------------
/section-06/waiter-service/src/main/java/takeout/waiterservice/model/TakeOutOrder.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | import javax.persistence.Column;
11 | import javax.persistence.Entity;
12 | import javax.persistence.GeneratedValue;
13 | import javax.persistence.Id;
14 | import javax.xml.bind.annotation.XmlRootElement;
15 | import java.util.Date;
16 |
17 | @Data
18 | @NoArgsConstructor
19 | @AllArgsConstructor
20 | @Builder
21 | @JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler", "fieldHandler"})
22 | @Entity
23 | @XmlRootElement
24 | public class TakeOutOrder {
25 | @Id
26 | @GeneratedValue
27 | private Long id;
28 | private String items;
29 | private String customer;
30 | private String waiter;
31 | private Long price;
32 | private String state;
33 | @Column(updatable = false)
34 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
35 | private Date createTime;
36 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
37 | private Date modifyTime;
38 | }
39 |
--------------------------------------------------------------------------------
/section-06/waiter-service/src/main/java/takeout/waiterservice/repository/PaymentRepository.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import takeout.waiterservice.model.Payment;
5 |
6 | import java.util.Optional;
7 |
8 | public interface PaymentRepository extends JpaRepository {
9 | Optional findByOrderId(Long orderId);
10 | }
11 |
--------------------------------------------------------------------------------
/section-06/waiter-service/src/main/java/takeout/waiterservice/repository/TakeOutOrderRepository.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import takeout.waiterservice.model.TakeOutOrder;
5 |
6 | import java.util.List;
7 |
8 | public interface TakeOutOrderRepository extends JpaRepository {
9 | List findByCustomerOrderById(String customer);
10 | }
11 |
--------------------------------------------------------------------------------
/section-06/waiter-service/src/main/java/takeout/waiterservice/service/OrderService.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.service;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.stereotype.Service;
5 | import takeout.waiterservice.model.TakeOutOrder;
6 | import takeout.waiterservice.repository.TakeOutOrderRepository;
7 |
8 | import javax.persistence.EntityNotFoundException;
9 | import java.util.Date;
10 | import java.util.List;
11 |
12 | @Service
13 | public class OrderService {
14 | @Autowired
15 | private TakeOutOrderRepository orderRepository;
16 |
17 | public List getAllOrders() {
18 | return orderRepository.findAll();
19 | }
20 |
21 | public TakeOutOrder getOrder(Long id) {
22 | return id == null ? null : orderRepository.findById(id)
23 | .orElseThrow(() -> new EntityNotFoundException("Order " + id + " is NOT found."));
24 | }
25 |
26 | public void deleteOrder(Long id) {
27 | orderRepository.delete(
28 | orderRepository.findById(id)
29 | .orElseThrow(() -> new EntityNotFoundException("Order " + id + " is NOT found."))
30 | );
31 | }
32 |
33 | public TakeOutOrder createOrder(TakeOutOrder order) {
34 | if (order != null) {
35 | order.setId(null);
36 | order.setWaiter("Tony");
37 | order.setState("I");
38 | order.setCreateTime(new Date());
39 | order.setModifyTime(new Date());
40 | orderRepository.save(order);
41 | }
42 | return order;
43 | }
44 |
45 | public void payOrder(Long id) {
46 | TakeOutOrder order = orderRepository.getOne(id);
47 | order.setState("P");
48 | order.setModifyTime(new Date());
49 | orderRepository.save(order);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/section-06/waiter-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.output.ansi.enabled=ALWAYS
--------------------------------------------------------------------------------
/section-06/waiter-service/src/main/resources/bootstrap.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=waiter-service
--------------------------------------------------------------------------------
/section-06/waiter-service/src/test/java/takeout/waiterservice/WaiterServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class WaiterServiceApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-07/README.md:
--------------------------------------------------------------------------------
1 | # Section 07
2 |
3 | 在Section 06的基础上,增加Hystrix作为断路器。
4 |
5 | * 复用Section 06的waiter-service
6 | * 修改customer-service,增加Hystrix支持
7 | * 新建一个HystrixDashboard
8 |
9 |
--------------------------------------------------------------------------------
/section-07/customer-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-07/customer-service/src/main/java/takeout/customerservice/CustomerServiceApplication.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
7 | import org.springframework.cloud.client.loadbalancer.LoadBalanced;
8 | import org.springframework.context.annotation.Bean;
9 | import org.springframework.web.client.RestTemplate;
10 |
11 | @SpringBootApplication
12 | @EnableDiscoveryClient
13 | @EnableCircuitBreaker
14 | public class CustomerServiceApplication {
15 |
16 | public static void main(String[] args) {
17 | SpringApplication.run(CustomerServiceApplication.class, args);
18 | }
19 |
20 | @Bean
21 | @LoadBalanced
22 | public RestTemplate restTemplate() {
23 | return new RestTemplate();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/section-07/customer-service/src/main/java/takeout/customerservice/SimpleOrderRunner.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.beans.factory.annotation.Value;
6 | import org.springframework.boot.ApplicationArguments;
7 | import org.springframework.boot.ApplicationRunner;
8 | import org.springframework.core.ParameterizedTypeReference;
9 | import org.springframework.http.HttpMethod;
10 | import org.springframework.http.ResponseEntity;
11 | import org.springframework.stereotype.Component;
12 | import org.springframework.web.client.RestTemplate;
13 | import org.springframework.web.util.UriComponentsBuilder;
14 | import takeout.customerservice.model.Order;
15 | import takeout.customerservice.model.Payment;
16 |
17 | import java.net.URI;
18 | import java.util.List;
19 |
20 | @Component
21 | @Slf4j
22 | public class SimpleOrderRunner implements ApplicationRunner {
23 | @Autowired
24 | private TakeOutService takeOutService;
25 |
26 | @Override
27 | public void run(ApplicationArguments args) throws Exception {
28 | for (int i = 0; i < 100; i++) {
29 | if (takeOutService.askHowLongToWait() >=0) {
30 | break;
31 | }
32 | Thread.sleep(5000);
33 | }
34 | Long orderId = takeOutService.makeAnOrder();
35 | takeOutService.payTheOrder(orderId);
36 | }
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/section-07/customer-service/src/main/java/takeout/customerservice/model/Order.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice.model;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @NoArgsConstructor
10 | @AllArgsConstructor
11 | @Builder
12 | public class Order {
13 | private Long id;
14 | private String items;
15 | private String customer;
16 | private String waiter;
17 | private Long price;
18 | private String state;
19 | }
20 |
--------------------------------------------------------------------------------
/section-07/customer-service/src/main/java/takeout/customerservice/model/Payment.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice.model;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @AllArgsConstructor
10 | @NoArgsConstructor
11 | @Builder
12 | public class Payment {
13 | private Long id;
14 | private Long orderId;
15 | private Long price;
16 | private String state;
17 | }
18 |
--------------------------------------------------------------------------------
/section-07/customer-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | customer.name=Natasha
2 | waiter.url=http://waiter-service
3 |
4 | server.port=7080
5 | spring.output.ansi.enabled=ALWAYS
6 |
7 | management.endpoints.web.exposure.include=health,hystrix.stream
8 |
--------------------------------------------------------------------------------
/section-07/customer-service/src/main/resources/bootstrap.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=customer-service
--------------------------------------------------------------------------------
/section-07/customer-service/src/test/java/takeout/customerservice/CustomerServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class CustomerServiceApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-07/hystrix-dashboard/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-07/hystrix-dashboard/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | takeout
7 | hystrix-dashboard
8 | 0.0.1-SNAPSHOT
9 | jar
10 |
11 | hystrix-dashboard
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.0.5.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 | Finchley.SR1
26 |
27 |
28 |
29 |
30 | org.springframework.cloud
31 | spring-cloud-starter-netflix-hystrix-dashboard
32 |
33 |
34 |
35 | org.springframework.boot
36 | spring-boot-starter-test
37 | test
38 |
39 |
40 |
41 |
42 |
43 |
44 | org.springframework.cloud
45 | spring-cloud-dependencies
46 | ${spring-cloud.version}
47 | pom
48 | import
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | org.springframework.boot
57 | spring-boot-maven-plugin
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/section-07/hystrix-dashboard/src/main/java/takeout/hystrixdashboard/HystrixDashboardApplication.java:
--------------------------------------------------------------------------------
1 | package takeout.hystrixdashboard;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
6 |
7 | @SpringBootApplication
8 | @EnableHystrixDashboard
9 | public class HystrixDashboardApplication {
10 |
11 | public static void main(String[] args) {
12 | SpringApplication.run(HystrixDashboardApplication.class, args);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/section-07/hystrix-dashboard/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | server.port=6080
--------------------------------------------------------------------------------
/section-07/hystrix-dashboard/src/test/java/takeout/hystrixdashboard/HystrixDashboardApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.hystrixdashboard;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class HystrixDashboardApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-08/README.md:
--------------------------------------------------------------------------------
1 | # Section 08
2 |
3 | 在Section 06的基础上,使用Spring Cloud Config添加了配置中心功能,配置中心使用的是Zookeeper存储。
4 |
5 |
6 |
--------------------------------------------------------------------------------
/section-08/waiter-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-08/waiter-service/src/main/java/takeout/waiterservice/DataInitializerRunner.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.boot.ApplicationArguments;
5 | import org.springframework.boot.ApplicationRunner;
6 | import org.springframework.stereotype.Component;
7 | import takeout.waiterservice.model.TakeOutOrder;
8 | import takeout.waiterservice.repository.TakeOutOrderRepository;
9 |
10 | import java.util.Date;
11 |
12 | @Component
13 | public class DataInitializerRunner implements ApplicationRunner {
14 | @Autowired
15 | private TakeOutOrderRepository orderRepository;
16 | @Autowired
17 | private Waiter waiter;
18 |
19 | @Override
20 | public void run(ApplicationArguments args) throws Exception {
21 | TakeOutOrder order = TakeOutOrder.builder()
22 | .customer("Steve")
23 | .waiter(waiter.getWaiterName())
24 | .items("Hamburger")
25 | .price(1000L)
26 | .state("I")
27 | .createTime(new Date())
28 | .modifyTime(new Date()).build();
29 | orderRepository.save(order);
30 |
31 | order = TakeOutOrder.builder()
32 | .customer("Bruce")
33 | .waiter(waiter.getWaiterName())
34 | .items("Sandwich")
35 | .price(1000L)
36 | .state("I")
37 | .createTime(new Date())
38 | .modifyTime(new Date()).build();
39 | orderRepository.save(order);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/section-08/waiter-service/src/main/java/takeout/waiterservice/Waiter.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import lombok.Data;
4 | import org.springframework.beans.factory.annotation.Value;
5 | import org.springframework.cloud.context.config.annotation.RefreshScope;
6 | import org.springframework.stereotype.Component;
7 |
8 | @Component
9 | @RefreshScope
10 | @Data
11 | public class Waiter {
12 | @Value("${prefix.name}")
13 | private String prefix;
14 | @Value("${random.int}")
15 | private int number;
16 |
17 | public String getWaiterName() {
18 | return prefix + "-" + number;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/section-08/waiter-service/src/main/java/takeout/waiterservice/WaiterServiceApplication.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
6 |
7 | @SpringBootApplication
8 | @EnableDiscoveryClient
9 | public class WaiterServiceApplication {
10 |
11 | public static void main(String[] args) {
12 | SpringApplication.run(WaiterServiceApplication.class, args);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/section-08/waiter-service/src/main/java/takeout/waiterservice/controller/ExceptionControllerAdvice.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.http.HttpStatus;
4 | import org.springframework.web.bind.annotation.ControllerAdvice;
5 | import org.springframework.web.bind.annotation.ExceptionHandler;
6 | import org.springframework.web.bind.annotation.ResponseStatus;
7 |
8 | import javax.persistence.EntityNotFoundException;
9 | import java.util.Collections;
10 | import java.util.Map;
11 |
12 | @ControllerAdvice
13 | public class ExceptionControllerAdvice {
14 | @ExceptionHandler(EntityNotFoundException.class)
15 | @ResponseStatus(HttpStatus.NOT_FOUND)
16 | public Map entityNotFound(EntityNotFoundException e) {
17 | return Collections.singletonMap("message", e.getMessage());
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/section-08/waiter-service/src/main/java/takeout/waiterservice/controller/OrderController.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.web.bind.annotation.DeleteMapping;
6 | import org.springframework.web.bind.annotation.GetMapping;
7 | import org.springframework.web.bind.annotation.PathVariable;
8 | import org.springframework.web.bind.annotation.PostMapping;
9 | import org.springframework.web.bind.annotation.RequestBody;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.ResponseStatus;
12 | import org.springframework.web.bind.annotation.RestController;
13 | import takeout.waiterservice.model.TakeOutOrder;
14 | import takeout.waiterservice.service.OrderService;
15 |
16 | import java.util.List;
17 |
18 | @RestController
19 | @RequestMapping("/orders")
20 | public class OrderController {
21 | @Autowired
22 | private OrderService orderService;
23 |
24 | @GetMapping("/{id}")
25 | public TakeOutOrder getOrder(@PathVariable Long id) {
26 | return orderService.getOrder(id);
27 | }
28 |
29 | @DeleteMapping("/{id}")
30 | public List deleteOrder(@PathVariable Long id) {
31 | orderService.deleteOrder(id);
32 | return orderService.getAllOrders();
33 | }
34 |
35 | @PostMapping
36 | @ResponseStatus(HttpStatus.CREATED)
37 | public TakeOutOrder createOrder(@RequestBody TakeOutOrder order) {
38 | return orderService.createOrder(order);
39 | }
40 |
41 | @GetMapping
42 | public List getAllOrder() {
43 | return orderService.getAllOrders();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/section-08/waiter-service/src/main/java/takeout/waiterservice/controller/PaymentController.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.web.bind.annotation.PathVariable;
6 | import org.springframework.web.bind.annotation.RequestBody;
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 | import org.springframework.web.bind.annotation.RestController;
11 | import takeout.waiterservice.model.Payment;
12 | import takeout.waiterservice.service.PaymentService;
13 |
14 | @RestController
15 | @RequestMapping("/orders/{id}/payment")
16 | public class PaymentController {
17 | @Autowired
18 | private PaymentService paymentService;
19 |
20 | @RequestMapping(method = RequestMethod.POST)
21 | @ResponseStatus(HttpStatus.CREATED)
22 | public Payment createPayment(@PathVariable Long id) {
23 | return paymentService.createPayment(id);
24 | }
25 |
26 | @RequestMapping(method = RequestMethod.GET)
27 | public Payment getPayment(@PathVariable Long id) {
28 | return paymentService.getPayment(id);
29 | }
30 |
31 | @RequestMapping(method = RequestMethod.PUT)
32 | public Payment updatePayment(@PathVariable Long id, @RequestBody Payment payment) {
33 | return paymentService.updatePayment(id, payment);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/section-08/waiter-service/src/main/java/takeout/waiterservice/model/Payment.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.persistence.Column;
10 | import javax.persistence.Entity;
11 | import javax.persistence.GeneratedValue;
12 | import javax.persistence.Id;
13 | import javax.xml.bind.annotation.XmlRootElement;
14 | import java.util.Date;
15 |
16 | @Entity
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @XmlRootElement
22 | public class Payment {
23 | @Id
24 | @GeneratedValue
25 | private Long id;
26 | @Column(updatable = false)
27 | private Long orderId;
28 | private Long price;
29 | private String state;
30 | @Column(updatable = false)
31 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
32 | private Date createTime;
33 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
34 | private Date modifyTime;
35 | }
36 |
--------------------------------------------------------------------------------
/section-08/waiter-service/src/main/java/takeout/waiterservice/model/TakeOutOrder.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | import javax.persistence.Column;
11 | import javax.persistence.Entity;
12 | import javax.persistence.GeneratedValue;
13 | import javax.persistence.Id;
14 | import javax.xml.bind.annotation.XmlRootElement;
15 | import java.util.Date;
16 |
17 | @Data
18 | @NoArgsConstructor
19 | @AllArgsConstructor
20 | @Builder
21 | @JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler", "fieldHandler"})
22 | @Entity
23 | @XmlRootElement
24 | public class TakeOutOrder {
25 | @Id
26 | @GeneratedValue
27 | private Long id;
28 | private String items;
29 | private String customer;
30 | private String waiter;
31 | private Long price;
32 | private String state;
33 | @Column(updatable = false)
34 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
35 | private Date createTime;
36 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
37 | private Date modifyTime;
38 | }
39 |
--------------------------------------------------------------------------------
/section-08/waiter-service/src/main/java/takeout/waiterservice/repository/PaymentRepository.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import takeout.waiterservice.model.Payment;
5 |
6 | import java.util.Optional;
7 |
8 | public interface PaymentRepository extends JpaRepository {
9 | Optional findByOrderId(Long orderId);
10 | }
11 |
--------------------------------------------------------------------------------
/section-08/waiter-service/src/main/java/takeout/waiterservice/repository/TakeOutOrderRepository.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import takeout.waiterservice.model.TakeOutOrder;
5 |
6 | import java.util.List;
7 |
8 | public interface TakeOutOrderRepository extends JpaRepository {
9 | List findByCustomerOrderById(String customer);
10 | }
11 |
--------------------------------------------------------------------------------
/section-08/waiter-service/src/main/java/takeout/waiterservice/service/OrderService.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.service;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.stereotype.Service;
5 | import takeout.waiterservice.Waiter;
6 | import takeout.waiterservice.model.TakeOutOrder;
7 | import takeout.waiterservice.repository.TakeOutOrderRepository;
8 |
9 | import javax.persistence.EntityNotFoundException;
10 | import java.util.Date;
11 | import java.util.List;
12 |
13 | @Service
14 | public class OrderService {
15 | @Autowired
16 | private TakeOutOrderRepository orderRepository;
17 | @Autowired
18 | private Waiter waiter;
19 |
20 | public List getAllOrders() {
21 | return orderRepository.findAll();
22 | }
23 |
24 | public TakeOutOrder getOrder(Long id) {
25 | return id == null ? null : orderRepository.findById(id)
26 | .orElseThrow(() -> new EntityNotFoundException("Order " + id + " is NOT found."));
27 | }
28 |
29 | public void deleteOrder(Long id) {
30 | orderRepository.delete(
31 | orderRepository.findById(id)
32 | .orElseThrow(() -> new EntityNotFoundException("Order " + id + " is NOT found."))
33 | );
34 | }
35 |
36 | public TakeOutOrder createOrder(TakeOutOrder order) {
37 | if (order != null) {
38 | order.setId(null);
39 | order.setWaiter(waiter.getWaiterName());
40 | order.setState("I");
41 | order.setCreateTime(new Date());
42 | order.setModifyTime(new Date());
43 | orderRepository.save(order);
44 | }
45 | return order;
46 | }
47 |
48 | public void payOrder(Long id) {
49 | TakeOutOrder order = orderRepository.getOne(id);
50 | order.setState("P");
51 | order.setModifyTime(new Date());
52 | orderRepository.save(order);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/section-08/waiter-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.output.ansi.enabled=ALWAYS
2 | management.endpoints.web.exposure.include=health,refresh
3 |
--------------------------------------------------------------------------------
/section-08/waiter-service/src/main/resources/bootstrap.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=waiter-service
2 |
3 | spring.cloud.zookeeper.config.enabled=true
4 | spring.cloud.zookeeper.connect-string=localhost:2181
5 |
--------------------------------------------------------------------------------
/section-08/waiter-service/src/test/java/takeout/waiterservice/WaiterServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class WaiterServiceApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-09/README.md:
--------------------------------------------------------------------------------
1 | # Section 09
2 |
3 | 基于Spring Cloud Stream接入了RabbitMQ,实现了完整的下单、付款、制作、取餐的过程。
4 |
5 | 需要在本地启动一个RabbitMQ:
6 |
7 | ```
8 | docker run -d --hostname my-rabbit --name some-rabbit -p 9888:15672 -p 5672:5672 rabbitmq:3.6-management
9 | ```
--------------------------------------------------------------------------------
/section-09/chef-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-09/chef-service/src/main/java/takeout/chefservice/ChefServiceApplication.java:
--------------------------------------------------------------------------------
1 | package takeout.chefservice;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.springframework.beans.factory.annotation.Value;
5 | import org.springframework.boot.SpringApplication;
6 | import org.springframework.boot.autoconfigure.SpringBootApplication;
7 | import org.springframework.cloud.stream.annotation.EnableBinding;
8 | import org.springframework.cloud.stream.annotation.StreamListener;
9 | //import org.springframework.integration.annotation.Transformer;
10 | import org.springframework.messaging.handler.annotation.SendTo;
11 |
12 | @SpringBootApplication
13 | @EnableBinding(TakeOutStream.class)
14 | @Slf4j
15 | public class ChefServiceApplication {
16 | @Value("${chef.name}-${random.int}")
17 | private String chef;
18 |
19 | public static void main(String[] args) {
20 | SpringApplication.run(ChefServiceApplication.class, args);
21 | }
22 |
23 | @StreamListener("orderRequests")
24 | @SendTo("finishedOrders")
25 | // @Transformer(inputChannel = "orderRequests", outputChannel = "finishedOrders")
26 | public TakeOutOrder processOrder(TakeOutOrder request) {
27 | log.info("Receiving Order: {}", request);
28 | log.info("Cocking order {}...", request.getId());
29 | try {
30 | Thread.sleep(100);
31 | } catch (InterruptedException e) {
32 | }
33 | request.setChef(chef);
34 | request.setState("C");
35 | return request;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/section-09/chef-service/src/main/java/takeout/chefservice/TakeOutOrder.java:
--------------------------------------------------------------------------------
1 | package takeout.chefservice;
2 |
3 | import lombok.Data;
4 |
5 | @Data
6 | public class TakeOutOrder {
7 | private Long id;
8 | private String items;
9 | private String chef;
10 | private String state;
11 | }
12 |
--------------------------------------------------------------------------------
/section-09/chef-service/src/main/java/takeout/chefservice/TakeOutStream.java:
--------------------------------------------------------------------------------
1 | package takeout.chefservice;
2 |
3 | import org.springframework.cloud.stream.annotation.Input;
4 | import org.springframework.cloud.stream.annotation.Output;
5 | import org.springframework.messaging.MessageChannel;
6 | import org.springframework.messaging.SubscribableChannel;
7 |
8 | public interface TakeOutStream {
9 | @Output
10 | MessageChannel finishedOrders();
11 | @Input
12 | SubscribableChannel orderRequests();
13 | }
14 |
--------------------------------------------------------------------------------
/section-09/chef-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | server.port=9080
2 | spring.output.ansi.enabled=ALWAYS
3 |
4 | chef.name=Peter
5 |
6 | spring.rabbitmq.host=localhost
7 | spring.rabbitmq.port=5672
8 | spring.rabbitmq.username=guest
9 | spring.rabbitmq.password=guest
10 |
11 | spring.cloud.stream.bindinds.default.binder=rabbit
12 | spring.cloud.stream.binders.rabbit.type=rabbit
13 |
14 | spring.cloud.stream.bindings.orderRequests.group=chef-service
--------------------------------------------------------------------------------
/section-09/chef-service/src/test/java/takeout/chefservice/ChefServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.chefservice;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class ChefServiceApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-09/customer-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-09/customer-service/src/main/java/takeout/customerservice/CustomerServiceApplication.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
7 | import org.springframework.cloud.client.loadbalancer.LoadBalanced;
8 | import org.springframework.cloud.stream.annotation.EnableBinding;
9 | import org.springframework.cloud.stream.annotation.StreamListener;
10 | import org.springframework.context.annotation.Bean;
11 | import org.springframework.web.client.RestTemplate;
12 | import takeout.customerservice.model.TakeOutOrder;
13 |
14 | @SpringBootApplication
15 | @EnableDiscoveryClient
16 | @EnableBinding(TakeOutStream.class)
17 | @Slf4j
18 | public class CustomerServiceApplication {
19 | public static void main(String[] args) {
20 | SpringApplication.run(CustomerServiceApplication.class, args);
21 | }
22 |
23 | @Bean
24 | @LoadBalanced
25 | public RestTemplate restTemplate() {
26 | return new RestTemplate();
27 | }
28 |
29 | @StreamListener(target = "takeoutFood", condition = "headers['customer']=='${customer.name}'")
30 | public void takeoutFood(TakeOutOrder takeOutOrder) {
31 | log.info("I've taken the food {}", takeOutOrder);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/section-09/customer-service/src/main/java/takeout/customerservice/TakeOutStream.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice;
2 |
3 | import org.springframework.cloud.stream.annotation.Input;
4 | import org.springframework.cloud.stream.annotation.Output;
5 | import org.springframework.messaging.MessageChannel;
6 | import org.springframework.messaging.SubscribableChannel;
7 |
8 | public interface TakeOutStream {
9 | @Input
10 | SubscribableChannel takeoutFood();
11 | }
12 |
--------------------------------------------------------------------------------
/section-09/customer-service/src/main/java/takeout/customerservice/model/Payment.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice.model;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @AllArgsConstructor
10 | @NoArgsConstructor
11 | @Builder
12 | public class Payment {
13 | private Long id;
14 | private Long orderId;
15 | private Long price;
16 | private String state;
17 | }
18 |
--------------------------------------------------------------------------------
/section-09/customer-service/src/main/java/takeout/customerservice/model/TakeOutOrder.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice.model;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @NoArgsConstructor
10 | @AllArgsConstructor
11 | @Builder
12 | public class TakeOutOrder {
13 | private Long id;
14 | private String items;
15 | private String customer;
16 | private String waiter;
17 | private String chef;
18 | private Long price;
19 | private String state;
20 | }
21 |
--------------------------------------------------------------------------------
/section-09/customer-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | customer.name=Natasha-${server.port}
2 | waiter.url=http://waiter-service
3 |
4 | server.port=7080
5 | spring.output.ansi.enabled=ALWAYS
6 |
7 | spring.rabbitmq.host=localhost
8 | spring.rabbitmq.port=5672
9 | spring.rabbitmq.username=guest
10 | spring.rabbitmq.password=guest
11 |
12 | spring.cloud.stream.bindinds.default.binder=rabbit
13 | spring.cloud.stream.binders.rabbit.type=rabbit
14 |
15 | spring.cloud.stream.bindings.takeoutFood.group=customer-service
16 |
--------------------------------------------------------------------------------
/section-09/customer-service/src/main/resources/bootstrap.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=customer-service
--------------------------------------------------------------------------------
/section-09/customer-service/src/test/java/takeout/customerservice/CustomerServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class CustomerServiceApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-09/waiter-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-09/waiter-service/src/main/java/takeout/waiterservice/DataInitializerRunner.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.boot.ApplicationArguments;
5 | import org.springframework.boot.ApplicationRunner;
6 | import org.springframework.stereotype.Component;
7 | import takeout.waiterservice.model.TakeOutOrder;
8 | import takeout.waiterservice.repository.TakeOutOrderRepository;
9 |
10 | import java.util.Date;
11 |
12 | @Component
13 | public class DataInitializerRunner implements ApplicationRunner {
14 | @Autowired
15 | private TakeOutOrderRepository orderRepository;
16 | @Autowired
17 | private Waiter waiter;
18 |
19 | @Override
20 | public void run(ApplicationArguments args) throws Exception {
21 | TakeOutOrder order = TakeOutOrder.builder()
22 | .customer("Steve")
23 | .waiter(waiter.getWaiterName())
24 | .items("Hamburger")
25 | .price(1000L)
26 | .state("I")
27 | .createTime(new Date())
28 | .modifyTime(new Date()).build();
29 | orderRepository.save(order);
30 |
31 | order = TakeOutOrder.builder()
32 | .customer("Bruce")
33 | .waiter(waiter.getWaiterName())
34 | .items("Sandwich")
35 | .price(1000L)
36 | .state("I")
37 | .createTime(new Date())
38 | .modifyTime(new Date()).build();
39 | orderRepository.save(order);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/section-09/waiter-service/src/main/java/takeout/waiterservice/TakeOutStream.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.cloud.stream.annotation.Input;
4 | import org.springframework.cloud.stream.annotation.Output;
5 | import org.springframework.messaging.MessageChannel;
6 | import org.springframework.messaging.SubscribableChannel;
7 |
8 | public interface TakeOutStream {
9 | @Input
10 | SubscribableChannel finishedOrders();
11 | @Output
12 | MessageChannel orderRequests();
13 | @Output
14 | MessageChannel takeoutFood();
15 | }
16 |
--------------------------------------------------------------------------------
/section-09/waiter-service/src/main/java/takeout/waiterservice/Waiter.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import lombok.Data;
4 | import org.springframework.beans.factory.annotation.Value;
5 | import org.springframework.cloud.context.config.annotation.RefreshScope;
6 | import org.springframework.stereotype.Component;
7 |
8 | @Component
9 | @RefreshScope
10 | @Data
11 | public class Waiter {
12 | @Value("${prefix.name}")
13 | private String prefix;
14 | @Value("${random.int}")
15 | private int number;
16 |
17 | public String getWaiterName() {
18 | return prefix + "-" + number;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/section-09/waiter-service/src/main/java/takeout/waiterservice/WaiterServiceApplication.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
6 | import org.springframework.cloud.stream.annotation.EnableBinding;
7 |
8 | @SpringBootApplication
9 | @EnableDiscoveryClient
10 | @EnableBinding(TakeOutStream.class)
11 | public class WaiterServiceApplication {
12 |
13 | public static void main(String[] args) {
14 | SpringApplication.run(WaiterServiceApplication.class, args);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/section-09/waiter-service/src/main/java/takeout/waiterservice/controller/ExceptionControllerAdvice.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.http.HttpStatus;
4 | import org.springframework.web.bind.annotation.ControllerAdvice;
5 | import org.springframework.web.bind.annotation.ExceptionHandler;
6 | import org.springframework.web.bind.annotation.ResponseStatus;
7 |
8 | import javax.persistence.EntityNotFoundException;
9 | import java.util.Collections;
10 | import java.util.Map;
11 |
12 | @ControllerAdvice
13 | public class ExceptionControllerAdvice {
14 | @ExceptionHandler(EntityNotFoundException.class)
15 | @ResponseStatus(HttpStatus.NOT_FOUND)
16 | public Map entityNotFound(EntityNotFoundException e) {
17 | return Collections.singletonMap("message", e.getMessage());
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/section-09/waiter-service/src/main/java/takeout/waiterservice/controller/OrderController.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.web.bind.annotation.DeleteMapping;
6 | import org.springframework.web.bind.annotation.GetMapping;
7 | import org.springframework.web.bind.annotation.PathVariable;
8 | import org.springframework.web.bind.annotation.PostMapping;
9 | import org.springframework.web.bind.annotation.RequestBody;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.ResponseStatus;
12 | import org.springframework.web.bind.annotation.RestController;
13 | import takeout.waiterservice.model.TakeOutOrder;
14 | import takeout.waiterservice.service.OrderService;
15 |
16 | import java.util.List;
17 |
18 | @RestController
19 | @RequestMapping("/orders")
20 | public class OrderController {
21 | @Autowired
22 | private OrderService orderService;
23 |
24 | @GetMapping("/{id}")
25 | public TakeOutOrder getOrder(@PathVariable Long id) {
26 | return orderService.getOrder(id);
27 | }
28 |
29 | @DeleteMapping("/{id}")
30 | public List deleteOrder(@PathVariable Long id) {
31 | orderService.deleteOrder(id);
32 | return orderService.getAllOrders();
33 | }
34 |
35 | @PostMapping
36 | @ResponseStatus(HttpStatus.CREATED)
37 | public TakeOutOrder createOrder(@RequestBody TakeOutOrder order) {
38 | return orderService.createOrder(order);
39 | }
40 |
41 | @GetMapping
42 | public List getAllOrder() {
43 | return orderService.getAllOrders();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/section-09/waiter-service/src/main/java/takeout/waiterservice/controller/PaymentController.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.web.bind.annotation.PathVariable;
6 | import org.springframework.web.bind.annotation.RequestBody;
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 | import org.springframework.web.bind.annotation.RestController;
11 | import takeout.waiterservice.model.Payment;
12 | import takeout.waiterservice.service.PaymentService;
13 |
14 | @RestController
15 | @RequestMapping("/orders/{id}/payment")
16 | public class PaymentController {
17 | @Autowired
18 | private PaymentService paymentService;
19 |
20 | @RequestMapping(method = RequestMethod.POST)
21 | @ResponseStatus(HttpStatus.CREATED)
22 | public Payment createPayment(@PathVariable Long id) {
23 | return paymentService.createPayment(id);
24 | }
25 |
26 | @RequestMapping(method = RequestMethod.GET)
27 | public Payment getPayment(@PathVariable Long id) {
28 | return paymentService.getPayment(id);
29 | }
30 |
31 | @RequestMapping(method = RequestMethod.PUT)
32 | public Payment updatePayment(@PathVariable Long id, @RequestBody Payment payment) {
33 | return paymentService.updatePayment(id, payment);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/section-09/waiter-service/src/main/java/takeout/waiterservice/model/Payment.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.persistence.Column;
10 | import javax.persistence.Entity;
11 | import javax.persistence.GeneratedValue;
12 | import javax.persistence.Id;
13 | import javax.xml.bind.annotation.XmlRootElement;
14 | import java.util.Date;
15 |
16 | @Entity
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @XmlRootElement
22 | public class Payment {
23 | @Id
24 | @GeneratedValue
25 | private Long id;
26 | @Column(updatable = false)
27 | private Long orderId;
28 | private Long price;
29 | private String state;
30 | @Column(updatable = false)
31 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
32 | private Date createTime;
33 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
34 | private Date modifyTime;
35 | }
36 |
--------------------------------------------------------------------------------
/section-09/waiter-service/src/main/java/takeout/waiterservice/model/TakeOutOrder.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | import javax.persistence.Column;
11 | import javax.persistence.Entity;
12 | import javax.persistence.GeneratedValue;
13 | import javax.persistence.Id;
14 | import javax.xml.bind.annotation.XmlRootElement;
15 | import java.util.Date;
16 |
17 | @Data
18 | @NoArgsConstructor
19 | @AllArgsConstructor
20 | @Builder
21 | @JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler", "fieldHandler"})
22 | @Entity
23 | @XmlRootElement
24 | public class TakeOutOrder {
25 | @Id
26 | @GeneratedValue
27 | private Long id;
28 | private String items;
29 | private String customer;
30 | private String waiter;
31 | private String chef;
32 | private Long price;
33 | private String state;
34 | @Column(updatable = false)
35 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
36 | private Date createTime;
37 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
38 | private Date modifyTime;
39 | }
40 |
--------------------------------------------------------------------------------
/section-09/waiter-service/src/main/java/takeout/waiterservice/repository/PaymentRepository.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import takeout.waiterservice.model.Payment;
5 |
6 | import java.util.Optional;
7 |
8 | public interface PaymentRepository extends JpaRepository {
9 | Optional findByOrderId(Long orderId);
10 | }
11 |
--------------------------------------------------------------------------------
/section-09/waiter-service/src/main/java/takeout/waiterservice/repository/TakeOutOrderRepository.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import takeout.waiterservice.model.TakeOutOrder;
5 |
6 | import java.util.List;
7 |
8 | public interface TakeOutOrderRepository extends JpaRepository {
9 | List findByCustomerOrderById(String customer);
10 | }
11 |
--------------------------------------------------------------------------------
/section-09/waiter-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.output.ansi.enabled=ALWAYS
2 | management.endpoints.web.exposure.include=health,refresh
3 |
4 | spring.rabbitmq.host=localhost
5 | spring.rabbitmq.port=5672
6 | spring.rabbitmq.username=guest
7 | spring.rabbitmq.password=guest
8 |
9 | spring.cloud.stream.bindinds.default.binder=rabbit
10 | spring.cloud.stream.binders.rabbit.type=rabbit
11 |
12 | spring.cloud.stream.bindings.finishedOrders.group=waiter-service
--------------------------------------------------------------------------------
/section-09/waiter-service/src/main/resources/bootstrap.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=waiter-service
2 |
3 | spring.cloud.zookeeper.config.enabled=true
4 | spring.cloud.zookeeper.connect-string=localhost:2181
5 |
--------------------------------------------------------------------------------
/section-09/waiter-service/src/test/java/takeout/waiterservice/WaiterServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class WaiterServiceApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-10/README.md:
--------------------------------------------------------------------------------
1 | # Section 10
2 |
3 | 基于Section 09的代码,使用Spring Cloud Sleuth基于OpenZipkin实现了服务追踪,使用Web方式提交信息。
4 |
5 | * customer-service稍作修改,使用POST请求来触发后续操作
6 | * 所有服务接入spring-cloud-starter-zipkin
7 | * 在本地9411端口启动一个OpenZipkin
8 |
9 | ```
10 | docker run -d --name zipkin -p 9411:9411 openzipkin/zipkin
11 | ```
--------------------------------------------------------------------------------
/section-10/chef-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-10/chef-service/src/main/java/takeout/chefservice/ChefServiceApplication.java:
--------------------------------------------------------------------------------
1 | package takeout.chefservice;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.springframework.beans.factory.annotation.Value;
5 | import org.springframework.boot.SpringApplication;
6 | import org.springframework.boot.autoconfigure.SpringBootApplication;
7 | import org.springframework.cloud.stream.annotation.EnableBinding;
8 | import org.springframework.cloud.stream.annotation.StreamListener;
9 | //import org.springframework.integration.annotation.Transformer;
10 | import org.springframework.messaging.handler.annotation.SendTo;
11 |
12 | @SpringBootApplication
13 | @EnableBinding(TakeOutStream.class)
14 | @Slf4j
15 | public class ChefServiceApplication {
16 | @Value("${chef.name}-${random.int}")
17 | private String chef;
18 |
19 | public static void main(String[] args) {
20 | SpringApplication.run(ChefServiceApplication.class, args);
21 | }
22 |
23 | @StreamListener("orderRequests")
24 | @SendTo("finishedOrders")
25 | // @Transformer(inputChannel = "orderRequests", outputChannel = "finishedOrders")
26 | public TakeOutOrder processOrder(TakeOutOrder request) {
27 | log.info("Receiving Order: {}", request);
28 | log.info("Cocking order {}...", request.getId());
29 | try {
30 | Thread.sleep(100);
31 | } catch (InterruptedException e) {
32 | }
33 | request.setChef(chef);
34 | request.setState("C");
35 | return request;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/section-10/chef-service/src/main/java/takeout/chefservice/TakeOutOrder.java:
--------------------------------------------------------------------------------
1 | package takeout.chefservice;
2 |
3 | import lombok.Data;
4 |
5 | @Data
6 | public class TakeOutOrder {
7 | private Long id;
8 | private String items;
9 | private String chef;
10 | private String state;
11 | }
12 |
--------------------------------------------------------------------------------
/section-10/chef-service/src/main/java/takeout/chefservice/TakeOutStream.java:
--------------------------------------------------------------------------------
1 | package takeout.chefservice;
2 |
3 | import org.springframework.cloud.stream.annotation.Input;
4 | import org.springframework.cloud.stream.annotation.Output;
5 | import org.springframework.messaging.MessageChannel;
6 | import org.springframework.messaging.SubscribableChannel;
7 |
8 | public interface TakeOutStream {
9 | @Output
10 | MessageChannel finishedOrders();
11 | @Input
12 | SubscribableChannel orderRequests();
13 | }
14 |
--------------------------------------------------------------------------------
/section-10/chef-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | server.port=9080
2 | spring.output.ansi.enabled=ALWAYS
3 |
4 | chef.name=Peter
5 |
6 | spring.rabbitmq.host=localhost
7 | spring.rabbitmq.port=5672
8 | spring.rabbitmq.username=guest
9 | spring.rabbitmq.password=guest
10 |
11 | spring.cloud.stream.bindinds.default.binder=rabbit
12 | spring.cloud.stream.binders.rabbit.type=rabbit
13 |
14 | spring.cloud.stream.bindings.orderRequests.group=chef-service
15 |
16 | spring.sleuth.sampler.probability=1.0
17 | spring.zipkin.baseUrl=http://localhost:9411
18 | spring.zipkin.sender.type=web
--------------------------------------------------------------------------------
/section-10/chef-service/src/main/resources/bootstrap.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=chef-service
2 |
3 | spring.cloud.zookeeper.config.enabled=true
4 | spring.cloud.zookeeper.connect-string=localhost:2181
5 |
--------------------------------------------------------------------------------
/section-10/chef-service/src/test/java/takeout/chefservice/ChefServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.chefservice;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class ChefServiceApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-10/customer-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-10/customer-service/src/main/java/takeout/customerservice/TakeOutStream.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice;
2 |
3 | import org.springframework.cloud.stream.annotation.Input;
4 | import org.springframework.cloud.stream.annotation.Output;
5 | import org.springframework.messaging.MessageChannel;
6 | import org.springframework.messaging.SubscribableChannel;
7 |
8 | public interface TakeOutStream {
9 | @Input
10 | SubscribableChannel takeoutFood();
11 | }
12 |
--------------------------------------------------------------------------------
/section-10/customer-service/src/main/java/takeout/customerservice/model/Payment.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice.model;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @AllArgsConstructor
10 | @NoArgsConstructor
11 | @Builder
12 | public class Payment {
13 | private Long id;
14 | private Long orderId;
15 | private Long price;
16 | private String state;
17 | }
18 |
--------------------------------------------------------------------------------
/section-10/customer-service/src/main/java/takeout/customerservice/model/TakeOutOrder.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice.model;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @NoArgsConstructor
10 | @AllArgsConstructor
11 | @Builder
12 | public class TakeOutOrder {
13 | private Long id;
14 | private String items;
15 | private String customer;
16 | private String waiter;
17 | private String chef;
18 | private Long price;
19 | private String state;
20 | }
21 |
--------------------------------------------------------------------------------
/section-10/customer-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | customer.name=Natasha-${server.port}
2 | waiter.url=http://waiter-service
3 |
4 | server.port=7080
5 | spring.output.ansi.enabled=ALWAYS
6 |
7 | spring.rabbitmq.host=localhost
8 | spring.rabbitmq.port=5672
9 | spring.rabbitmq.username=guest
10 | spring.rabbitmq.password=guest
11 |
12 | spring.cloud.stream.bindinds.default.binder=rabbit
13 | spring.cloud.stream.binders.rabbit.type=rabbit
14 |
15 | spring.cloud.stream.bindings.takeoutFood.group=customer-service
16 |
17 | spring.sleuth.sampler.probability=1.0
18 | spring.zipkin.baseUrl=http://localhost:9411
19 | spring.zipkin.sender.type: web
--------------------------------------------------------------------------------
/section-10/customer-service/src/main/resources/bootstrap.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=customer-service
2 |
3 | spring.cloud.zookeeper.config.enabled=true
4 | spring.cloud.zookeeper.connect-string=localhost:2181
5 |
--------------------------------------------------------------------------------
/section-10/customer-service/src/test/java/takeout/customerservice/CustomerServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class CustomerServiceApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-10/waiter-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-10/waiter-service/src/main/java/takeout/waiterservice/DataInitializerRunner.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.boot.ApplicationArguments;
5 | import org.springframework.boot.ApplicationRunner;
6 | import org.springframework.stereotype.Component;
7 | import takeout.waiterservice.model.TakeOutOrder;
8 | import takeout.waiterservice.repository.TakeOutOrderRepository;
9 |
10 | import java.util.Date;
11 |
12 | @Component
13 | public class DataInitializerRunner implements ApplicationRunner {
14 | @Autowired
15 | private TakeOutOrderRepository orderRepository;
16 | @Autowired
17 | private Waiter waiter;
18 |
19 | @Override
20 | public void run(ApplicationArguments args) throws Exception {
21 | TakeOutOrder order = TakeOutOrder.builder()
22 | .customer("Steve")
23 | .waiter(waiter.getWaiterName())
24 | .items("Hamburger")
25 | .price(1000L)
26 | .state("I")
27 | .createTime(new Date())
28 | .modifyTime(new Date()).build();
29 | orderRepository.save(order);
30 |
31 | order = TakeOutOrder.builder()
32 | .customer("Bruce")
33 | .waiter(waiter.getWaiterName())
34 | .items("Sandwich")
35 | .price(1000L)
36 | .state("I")
37 | .createTime(new Date())
38 | .modifyTime(new Date()).build();
39 | orderRepository.save(order);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/section-10/waiter-service/src/main/java/takeout/waiterservice/TakeOutStream.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.cloud.stream.annotation.Input;
4 | import org.springframework.cloud.stream.annotation.Output;
5 | import org.springframework.messaging.MessageChannel;
6 | import org.springframework.messaging.SubscribableChannel;
7 |
8 | public interface TakeOutStream {
9 | @Input
10 | SubscribableChannel finishedOrders();
11 | @Output
12 | MessageChannel orderRequests();
13 | @Output
14 | MessageChannel takeoutFood();
15 | }
16 |
--------------------------------------------------------------------------------
/section-10/waiter-service/src/main/java/takeout/waiterservice/Waiter.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import lombok.Data;
4 | import org.springframework.beans.factory.annotation.Value;
5 | import org.springframework.cloud.context.config.annotation.RefreshScope;
6 | import org.springframework.stereotype.Component;
7 |
8 | @Component
9 | @RefreshScope
10 | @Data
11 | public class Waiter {
12 | @Value("${prefix.name}")
13 | private String prefix;
14 | @Value("${random.int}")
15 | private int number;
16 |
17 | public String getWaiterName() {
18 | return prefix + "-" + number;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/section-10/waiter-service/src/main/java/takeout/waiterservice/WaiterServiceApplication.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
6 | import org.springframework.cloud.stream.annotation.EnableBinding;
7 |
8 | @SpringBootApplication
9 | @EnableDiscoveryClient
10 | @EnableBinding(TakeOutStream.class)
11 | public class WaiterServiceApplication {
12 |
13 | public static void main(String[] args) {
14 | SpringApplication.run(WaiterServiceApplication.class, args);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/section-10/waiter-service/src/main/java/takeout/waiterservice/controller/ExceptionControllerAdvice.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.http.HttpStatus;
4 | import org.springframework.web.bind.annotation.ControllerAdvice;
5 | import org.springframework.web.bind.annotation.ExceptionHandler;
6 | import org.springframework.web.bind.annotation.ResponseStatus;
7 |
8 | import javax.persistence.EntityNotFoundException;
9 | import java.util.Collections;
10 | import java.util.Map;
11 |
12 | @ControllerAdvice
13 | public class ExceptionControllerAdvice {
14 | @ExceptionHandler(EntityNotFoundException.class)
15 | @ResponseStatus(HttpStatus.NOT_FOUND)
16 | public Map entityNotFound(EntityNotFoundException e) {
17 | return Collections.singletonMap("message", e.getMessage());
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/section-10/waiter-service/src/main/java/takeout/waiterservice/controller/OrderController.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.web.bind.annotation.DeleteMapping;
6 | import org.springframework.web.bind.annotation.GetMapping;
7 | import org.springframework.web.bind.annotation.PathVariable;
8 | import org.springframework.web.bind.annotation.PostMapping;
9 | import org.springframework.web.bind.annotation.RequestBody;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.ResponseStatus;
12 | import org.springframework.web.bind.annotation.RestController;
13 | import takeout.waiterservice.model.TakeOutOrder;
14 | import takeout.waiterservice.service.OrderService;
15 |
16 | import java.util.List;
17 |
18 | @RestController
19 | @RequestMapping("/orders")
20 | public class OrderController {
21 | @Autowired
22 | private OrderService orderService;
23 |
24 | @GetMapping("/{id}")
25 | public TakeOutOrder getOrder(@PathVariable Long id) {
26 | return orderService.getOrder(id);
27 | }
28 |
29 | @DeleteMapping("/{id}")
30 | public List deleteOrder(@PathVariable Long id) {
31 | orderService.deleteOrder(id);
32 | return orderService.getAllOrders();
33 | }
34 |
35 | @PostMapping
36 | @ResponseStatus(HttpStatus.CREATED)
37 | public TakeOutOrder createOrder(@RequestBody TakeOutOrder order) {
38 | return orderService.createOrder(order);
39 | }
40 |
41 | @GetMapping
42 | public List getAllOrder() {
43 | return orderService.getAllOrders();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/section-10/waiter-service/src/main/java/takeout/waiterservice/controller/PaymentController.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.web.bind.annotation.PathVariable;
6 | import org.springframework.web.bind.annotation.RequestBody;
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 | import org.springframework.web.bind.annotation.RestController;
11 | import takeout.waiterservice.model.Payment;
12 | import takeout.waiterservice.service.PaymentService;
13 |
14 | @RestController
15 | @RequestMapping("/orders/{id}/payment")
16 | public class PaymentController {
17 | @Autowired
18 | private PaymentService paymentService;
19 |
20 | @RequestMapping(method = RequestMethod.POST)
21 | @ResponseStatus(HttpStatus.CREATED)
22 | public Payment createPayment(@PathVariable Long id) {
23 | return paymentService.createPayment(id);
24 | }
25 |
26 | @RequestMapping(method = RequestMethod.GET)
27 | public Payment getPayment(@PathVariable Long id) {
28 | return paymentService.getPayment(id);
29 | }
30 |
31 | @RequestMapping(method = RequestMethod.PUT)
32 | public Payment updatePayment(@PathVariable Long id, @RequestBody Payment payment) {
33 | return paymentService.updatePayment(id, payment);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/section-10/waiter-service/src/main/java/takeout/waiterservice/model/Payment.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.persistence.Column;
10 | import javax.persistence.Entity;
11 | import javax.persistence.GeneratedValue;
12 | import javax.persistence.Id;
13 | import javax.xml.bind.annotation.XmlRootElement;
14 | import java.util.Date;
15 |
16 | @Entity
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @XmlRootElement
22 | public class Payment {
23 | @Id
24 | @GeneratedValue
25 | private Long id;
26 | @Column(updatable = false)
27 | private Long orderId;
28 | private Long price;
29 | private String state;
30 | @Column(updatable = false)
31 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
32 | private Date createTime;
33 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
34 | private Date modifyTime;
35 | }
36 |
--------------------------------------------------------------------------------
/section-10/waiter-service/src/main/java/takeout/waiterservice/model/TakeOutOrder.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | import javax.persistence.Column;
11 | import javax.persistence.Entity;
12 | import javax.persistence.GeneratedValue;
13 | import javax.persistence.Id;
14 | import javax.xml.bind.annotation.XmlRootElement;
15 | import java.util.Date;
16 |
17 | @Data
18 | @NoArgsConstructor
19 | @AllArgsConstructor
20 | @Builder
21 | @JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler", "fieldHandler"})
22 | @Entity
23 | @XmlRootElement
24 | public class TakeOutOrder {
25 | @Id
26 | @GeneratedValue
27 | private Long id;
28 | private String items;
29 | private String customer;
30 | private String waiter;
31 | private String chef;
32 | private Long price;
33 | private String state;
34 | @Column(updatable = false)
35 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
36 | private Date createTime;
37 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
38 | private Date modifyTime;
39 | }
40 |
--------------------------------------------------------------------------------
/section-10/waiter-service/src/main/java/takeout/waiterservice/repository/PaymentRepository.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import takeout.waiterservice.model.Payment;
5 |
6 | import java.util.Optional;
7 |
8 | public interface PaymentRepository extends JpaRepository {
9 | Optional findByOrderId(Long orderId);
10 | }
11 |
--------------------------------------------------------------------------------
/section-10/waiter-service/src/main/java/takeout/waiterservice/repository/TakeOutOrderRepository.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import takeout.waiterservice.model.TakeOutOrder;
5 |
6 | import java.util.List;
7 |
8 | public interface TakeOutOrderRepository extends JpaRepository {
9 | List findByCustomerOrderById(String customer);
10 | }
11 |
--------------------------------------------------------------------------------
/section-10/waiter-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.output.ansi.enabled=ALWAYS
2 | management.endpoints.web.exposure.include=health,refresh
3 |
4 | spring.rabbitmq.host=localhost
5 | spring.rabbitmq.port=5672
6 | spring.rabbitmq.username=guest
7 | spring.rabbitmq.password=guest
8 |
9 | spring.cloud.stream.bindinds.default.binder=rabbit
10 | spring.cloud.stream.binders.rabbit.type=rabbit
11 |
12 | spring.cloud.stream.bindings.finishedOrders.group=waiter-service
13 |
14 | spring.sleuth.sampler.percentage=1.0
15 | spring.zipkin.baseUrl=http://localhost:9411
16 | spring.zipkin.sender.type: web
--------------------------------------------------------------------------------
/section-10/waiter-service/src/main/resources/bootstrap.properties:
--------------------------------------------------------------------------------
1 | spring.application.name=waiter-service
2 |
3 | spring.cloud.zookeeper.config.enabled=true
4 | spring.cloud.zookeeper.connect-string=localhost:2181
5 |
--------------------------------------------------------------------------------
/section-10/waiter-service/src/test/java/takeout/waiterservice/WaiterServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class WaiterServiceApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-11/README.md:
--------------------------------------------------------------------------------
1 | # Section 11
2 |
3 | 容器化整个服务
4 |
5 | * 增加Dockerfile,将服务打包为Docker镜像
6 | * 修改程序配置,适应容器环境
7 | * 增加docker-compose.yml,演示Docker Compose
8 |
9 | 执行命令打包:
10 | ```
11 | mvn clean package docker:build -Dmaven.test.skip
12 | ```
13 |
14 | 通过docker命令启动:
15 | ```
16 | docker run -d --name rabbit -p 5672:5672 rabbitmq:3.6-management
17 | docker run -d --name zipkin -p 9411:9411 openzipkin/zipkin
18 | docker run -d --name zookeeper -p 2181:2181 zookeeper:3.5
19 |
20 | docker run --link rabbit:rabbit --link zookeeper:zookeeper --link zipkin:zipkin --name waiter-service takeout/waiter-service
21 | docker run --link rabbit:rabbit --link zookeeper:zookeeper --link zipkin:zipkin --name chef-service takeout/chef-service
22 | docker run --link rabbit:rabbit --link zookeeper:zookeeper --link zipkin:zipkin -p 8080:8080 --name customer-service takeout/customer-service
23 | ```
24 |
25 | 通过docker-compose启动:
26 | ```
27 | docker-compose -f docker-compose.yml up -d
28 | docker-compose scale chef-service=3
29 | docker-compose logs --tail 10 --follow customer-service
30 | ```
--------------------------------------------------------------------------------
/section-11/chef-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-11/chef-service/src/main/docker/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM java:8
2 | EXPOSE 8080
3 | ADD chef-service-0.0.1-SNAPSHOT.jar chef-service.jar
4 | ENTRYPOINT ["java", "-jar","/chef-service.jar"]
--------------------------------------------------------------------------------
/section-11/chef-service/src/main/java/takeout/chefservice/ChefServiceApplication.java:
--------------------------------------------------------------------------------
1 | package takeout.chefservice;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.springframework.beans.factory.annotation.Value;
5 | import org.springframework.boot.SpringApplication;
6 | import org.springframework.boot.autoconfigure.SpringBootApplication;
7 | import org.springframework.cloud.stream.annotation.EnableBinding;
8 | import org.springframework.cloud.stream.annotation.StreamListener;
9 | //import org.springframework.integration.annotation.Transformer;
10 | import org.springframework.messaging.handler.annotation.SendTo;
11 |
12 | @SpringBootApplication
13 | @EnableBinding(TakeOutStream.class)
14 | @Slf4j
15 | public class ChefServiceApplication {
16 | @Value("${chef.name}-${random.int}")
17 | private String chef;
18 |
19 | public static void main(String[] args) {
20 | SpringApplication.run(ChefServiceApplication.class, args);
21 | }
22 |
23 | @StreamListener("orderRequests")
24 | @SendTo("finishedOrders")
25 | // @Transformer(inputChannel = "orderRequests", outputChannel = "finishedOrders")
26 | public TakeOutOrder processOrder(TakeOutOrder request) {
27 | log.info("Receiving Order: {}", request);
28 | log.info("Cocking order {}...", request.getId());
29 | try {
30 | Thread.sleep(100);
31 | } catch (InterruptedException e) {
32 | }
33 | request.setChef(chef);
34 | request.setState("C");
35 | return request;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/section-11/chef-service/src/main/java/takeout/chefservice/TakeOutOrder.java:
--------------------------------------------------------------------------------
1 | package takeout.chefservice;
2 |
3 | import lombok.Data;
4 |
5 | @Data
6 | public class TakeOutOrder {
7 | private Long id;
8 | private String items;
9 | private String chef;
10 | private String state;
11 | }
12 |
--------------------------------------------------------------------------------
/section-11/chef-service/src/main/java/takeout/chefservice/TakeOutStream.java:
--------------------------------------------------------------------------------
1 | package takeout.chefservice;
2 |
3 | import org.springframework.cloud.stream.annotation.Input;
4 | import org.springframework.cloud.stream.annotation.Output;
5 | import org.springframework.messaging.MessageChannel;
6 | import org.springframework.messaging.SubscribableChannel;
7 |
8 | public interface TakeOutStream {
9 | @Output
10 | MessageChannel finishedOrders();
11 | @Input
12 | SubscribableChannel orderRequests();
13 | }
14 |
--------------------------------------------------------------------------------
/section-11/chef-service/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | chef.name: Peter
2 |
3 | server.port: 8080
4 |
5 | spring:
6 | output.ansi.enabled: ALWAYS
7 |
8 | rabbitmq:
9 | host: rabbit
10 | port: 5672
11 | username: guest
12 | password: guest
13 |
14 | cloud:
15 | stream:
16 | bindings:
17 | default.binder: rabbit
18 | orderRequests.group: chef-service
19 | binders.rabbit.type: rabbit
20 | zookeeper.discovery.preferIpAddress: true
21 | inetutils:
22 | ignoredInterfaces:
23 | - docker0
24 | - veth.*
25 |
26 | sleth.sampler.probability: 1.0
27 |
28 | zipkin:
29 | baseUrl: http://zipkin:9411
30 | sender.type: web
31 |
--------------------------------------------------------------------------------
/section-11/chef-service/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application.name: chef-service
3 |
4 | cloud.zookeeper:
5 | config.enabled: true
6 | connect-string: zookeeper:2181
7 |
--------------------------------------------------------------------------------
/section-11/chef-service/src/test/java/takeout/chefservice/ChefServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.chefservice;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class ChefServiceApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-11/customer-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-11/customer-service/src/main/docker/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM java:8
2 | EXPOSE 8080
3 | ADD customer-service-0.0.1-SNAPSHOT.jar customer-service.jar
4 | ENTRYPOINT ["java", "-jar","/customer-service.jar"]
--------------------------------------------------------------------------------
/section-11/customer-service/src/main/java/takeout/customerservice/TakeOutStream.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice;
2 |
3 | import org.springframework.cloud.stream.annotation.Input;
4 | import org.springframework.cloud.stream.annotation.Output;
5 | import org.springframework.messaging.MessageChannel;
6 | import org.springframework.messaging.SubscribableChannel;
7 |
8 | public interface TakeOutStream {
9 | @Input
10 | SubscribableChannel takeoutFood();
11 | }
12 |
--------------------------------------------------------------------------------
/section-11/customer-service/src/main/java/takeout/customerservice/model/Payment.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice.model;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @AllArgsConstructor
10 | @NoArgsConstructor
11 | @Builder
12 | public class Payment {
13 | private Long id;
14 | private Long orderId;
15 | private Long price;
16 | private String state;
17 | }
18 |
--------------------------------------------------------------------------------
/section-11/customer-service/src/main/java/takeout/customerservice/model/TakeOutOrder.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice.model;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @NoArgsConstructor
10 | @AllArgsConstructor
11 | @Builder
12 | public class TakeOutOrder {
13 | private Long id;
14 | private String items;
15 | private String customer;
16 | private String waiter;
17 | private String chef;
18 | private Long price;
19 | private String state;
20 | }
21 |
--------------------------------------------------------------------------------
/section-11/customer-service/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | customer.name: Natasha-${server.port}
2 |
3 | waiter.url: http://waiter-service
4 |
5 | server.port: 8080
6 |
7 | spring:
8 | output.ansi.enabled: ALWAYS
9 |
10 | rabbitmq:
11 | host: rabbit
12 | port: 5672
13 | username: guest
14 | password: guest
15 |
16 | cloud:
17 | stream:
18 | bindings:
19 | default.binder: rabbit
20 | takeoutFood.group: customer-service
21 | binders.rabbit.type: rabbit
22 | zookeeper.discovery.preferIpAddress: true
23 | inetutils:
24 | ignoredInterfaces:
25 | - docker0
26 | - veth.*
27 |
28 | sleth.sampler.probability: 1.0
29 |
30 | zipkin:
31 | baseUrl: http://zipkin:9411
32 | sender.type: web
33 |
--------------------------------------------------------------------------------
/section-11/customer-service/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application.name: customer-service
3 |
4 | cloud.zookeeper:
5 | config.enabled: true
6 | connect-string: zookeeper:2181
7 |
--------------------------------------------------------------------------------
/section-11/customer-service/src/test/java/takeout/customerservice/CustomerServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class CustomerServiceApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-11/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | zookeeper:
5 | image: zookeeper:3.5
6 | expose:
7 | - "2181"
8 |
9 | rabbit:
10 | image: rabbitmq:3.6-management
11 | expose:
12 | - "5671-5672"
13 | ports:
14 | - "9888:15672"
15 |
16 | zipkin:
17 | image: openzipkin/zipkin
18 | expose:
19 | - "9411"
20 | ports:
21 | - "9411:9411"
22 |
23 | chef-service:
24 | image: takeout/chef-service
25 | restart: always
26 | depends_on:
27 | - zookeeper
28 | - rabbit
29 | - zipkin
30 | links:
31 | - zookeeper
32 | - rabbit
33 | - zipkin
34 |
35 | customer-service:
36 | image: takeout/customer-service
37 | expose:
38 | - "8080"
39 | ports:
40 | - "8080:8080"
41 | depends_on:
42 | - waiter-service
43 | - chef-service
44 | links:
45 | - zookeeper
46 | - rabbit
47 | - zipkin
48 |
49 | waiter-service:
50 | image: takeout/waiter-service
51 | restart: always
52 | expose:
53 | - "8080"
54 | depends_on:
55 | - zookeeper
56 | - rabbit
57 | - zipkin
58 | links:
59 | - zookeeper
60 | - rabbit
61 | - zipkin
62 |
--------------------------------------------------------------------------------
/section-11/waiter-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-11/waiter-service/src/main/docker/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM java:8
2 | EXPOSE 8080
3 | ADD waiter-service-0.0.1-SNAPSHOT.jar waiter-service.jar
4 | ENTRYPOINT ["java", "-jar","/waiter-service.jar"]
--------------------------------------------------------------------------------
/section-11/waiter-service/src/main/java/takeout/waiterservice/DataInitializerRunner.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.boot.ApplicationArguments;
5 | import org.springframework.boot.ApplicationRunner;
6 | import org.springframework.stereotype.Component;
7 | import takeout.waiterservice.model.TakeOutOrder;
8 | import takeout.waiterservice.repository.TakeOutOrderRepository;
9 |
10 | import java.util.Date;
11 |
12 | @Component
13 | public class DataInitializerRunner implements ApplicationRunner {
14 | @Autowired
15 | private TakeOutOrderRepository orderRepository;
16 | @Autowired
17 | private Waiter waiter;
18 |
19 | @Override
20 | public void run(ApplicationArguments args) throws Exception {
21 | TakeOutOrder order = TakeOutOrder.builder()
22 | .customer("Steve")
23 | .waiter(waiter.getWaiterName())
24 | .items("Hamburger")
25 | .price(1000L)
26 | .state("I")
27 | .createTime(new Date())
28 | .modifyTime(new Date()).build();
29 | orderRepository.save(order);
30 |
31 | order = TakeOutOrder.builder()
32 | .customer("Bruce")
33 | .waiter(waiter.getWaiterName())
34 | .items("Sandwich")
35 | .price(1000L)
36 | .state("I")
37 | .createTime(new Date())
38 | .modifyTime(new Date()).build();
39 | orderRepository.save(order);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/section-11/waiter-service/src/main/java/takeout/waiterservice/TakeOutStream.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.cloud.stream.annotation.Input;
4 | import org.springframework.cloud.stream.annotation.Output;
5 | import org.springframework.messaging.MessageChannel;
6 | import org.springframework.messaging.SubscribableChannel;
7 |
8 | public interface TakeOutStream {
9 | @Input
10 | SubscribableChannel finishedOrders();
11 | @Output
12 | MessageChannel orderRequests();
13 | @Output
14 | MessageChannel takeoutFood();
15 | }
16 |
--------------------------------------------------------------------------------
/section-11/waiter-service/src/main/java/takeout/waiterservice/Waiter.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import lombok.Data;
4 | import org.springframework.beans.factory.annotation.Value;
5 | import org.springframework.cloud.context.config.annotation.RefreshScope;
6 | import org.springframework.stereotype.Component;
7 |
8 | @Component
9 | @RefreshScope
10 | @Data
11 | public class Waiter {
12 | @Value("${prefix.name}")
13 | private String prefix;
14 | @Value("${random.int}")
15 | private int number;
16 |
17 | public String getWaiterName() {
18 | return prefix + "-" + number;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/section-11/waiter-service/src/main/java/takeout/waiterservice/WaiterServiceApplication.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
6 | import org.springframework.cloud.stream.annotation.EnableBinding;
7 |
8 | @SpringBootApplication
9 | @EnableDiscoveryClient
10 | @EnableBinding(TakeOutStream.class)
11 | public class WaiterServiceApplication {
12 |
13 | public static void main(String[] args) {
14 | SpringApplication.run(WaiterServiceApplication.class, args);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/section-11/waiter-service/src/main/java/takeout/waiterservice/controller/ExceptionControllerAdvice.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.http.HttpStatus;
4 | import org.springframework.web.bind.annotation.ControllerAdvice;
5 | import org.springframework.web.bind.annotation.ExceptionHandler;
6 | import org.springframework.web.bind.annotation.ResponseStatus;
7 |
8 | import javax.persistence.EntityNotFoundException;
9 | import java.util.Collections;
10 | import java.util.Map;
11 |
12 | @ControllerAdvice
13 | public class ExceptionControllerAdvice {
14 | @ExceptionHandler(EntityNotFoundException.class)
15 | @ResponseStatus(HttpStatus.NOT_FOUND)
16 | public Map entityNotFound(EntityNotFoundException e) {
17 | return Collections.singletonMap("message", e.getMessage());
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/section-11/waiter-service/src/main/java/takeout/waiterservice/controller/OrderController.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.web.bind.annotation.DeleteMapping;
6 | import org.springframework.web.bind.annotation.GetMapping;
7 | import org.springframework.web.bind.annotation.PathVariable;
8 | import org.springframework.web.bind.annotation.PostMapping;
9 | import org.springframework.web.bind.annotation.RequestBody;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.ResponseStatus;
12 | import org.springframework.web.bind.annotation.RestController;
13 | import takeout.waiterservice.model.TakeOutOrder;
14 | import takeout.waiterservice.service.OrderService;
15 |
16 | import java.util.List;
17 |
18 | @RestController
19 | @RequestMapping("/orders")
20 | public class OrderController {
21 | @Autowired
22 | private OrderService orderService;
23 |
24 | @GetMapping("/{id}")
25 | public TakeOutOrder getOrder(@PathVariable Long id) {
26 | return orderService.getOrder(id);
27 | }
28 |
29 | @DeleteMapping("/{id}")
30 | public List deleteOrder(@PathVariable Long id) {
31 | orderService.deleteOrder(id);
32 | return orderService.getAllOrders();
33 | }
34 |
35 | @PostMapping
36 | @ResponseStatus(HttpStatus.CREATED)
37 | public TakeOutOrder createOrder(@RequestBody TakeOutOrder order) {
38 | return orderService.createOrder(order);
39 | }
40 |
41 | @GetMapping
42 | public List getAllOrder() {
43 | return orderService.getAllOrders();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/section-11/waiter-service/src/main/java/takeout/waiterservice/controller/PaymentController.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.web.bind.annotation.PathVariable;
6 | import org.springframework.web.bind.annotation.RequestBody;
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 | import org.springframework.web.bind.annotation.RestController;
11 | import takeout.waiterservice.model.Payment;
12 | import takeout.waiterservice.service.PaymentService;
13 |
14 | @RestController
15 | @RequestMapping("/orders/{id}/payment")
16 | public class PaymentController {
17 | @Autowired
18 | private PaymentService paymentService;
19 |
20 | @RequestMapping(method = RequestMethod.POST)
21 | @ResponseStatus(HttpStatus.CREATED)
22 | public Payment createPayment(@PathVariable Long id) {
23 | return paymentService.createPayment(id);
24 | }
25 |
26 | @RequestMapping(method = RequestMethod.GET)
27 | public Payment getPayment(@PathVariable Long id) {
28 | return paymentService.getPayment(id);
29 | }
30 |
31 | @RequestMapping(method = RequestMethod.PUT)
32 | public Payment updatePayment(@PathVariable Long id, @RequestBody Payment payment) {
33 | return paymentService.updatePayment(id, payment);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/section-11/waiter-service/src/main/java/takeout/waiterservice/model/Payment.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.persistence.Column;
10 | import javax.persistence.Entity;
11 | import javax.persistence.GeneratedValue;
12 | import javax.persistence.Id;
13 | import javax.xml.bind.annotation.XmlRootElement;
14 | import java.util.Date;
15 |
16 | @Entity
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @XmlRootElement
22 | public class Payment {
23 | @Id
24 | @GeneratedValue
25 | private Long id;
26 | @Column(updatable = false)
27 | private Long orderId;
28 | private Long price;
29 | private String state;
30 | @Column(updatable = false)
31 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
32 | private Date createTime;
33 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
34 | private Date modifyTime;
35 | }
36 |
--------------------------------------------------------------------------------
/section-11/waiter-service/src/main/java/takeout/waiterservice/model/TakeOutOrder.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | import javax.persistence.Column;
11 | import javax.persistence.Entity;
12 | import javax.persistence.GeneratedValue;
13 | import javax.persistence.Id;
14 | import javax.xml.bind.annotation.XmlRootElement;
15 | import java.util.Date;
16 |
17 | @Data
18 | @NoArgsConstructor
19 | @AllArgsConstructor
20 | @Builder
21 | @JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler", "fieldHandler"})
22 | @Entity
23 | @XmlRootElement
24 | public class TakeOutOrder {
25 | @Id
26 | @GeneratedValue
27 | private Long id;
28 | private String items;
29 | private String customer;
30 | private String waiter;
31 | private String chef;
32 | private Long price;
33 | private String state;
34 | @Column(updatable = false)
35 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
36 | private Date createTime;
37 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
38 | private Date modifyTime;
39 | }
40 |
--------------------------------------------------------------------------------
/section-11/waiter-service/src/main/java/takeout/waiterservice/repository/PaymentRepository.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import takeout.waiterservice.model.Payment;
5 |
6 | import java.util.Optional;
7 |
8 | public interface PaymentRepository extends JpaRepository {
9 | Optional findByOrderId(Long orderId);
10 | }
11 |
--------------------------------------------------------------------------------
/section-11/waiter-service/src/main/java/takeout/waiterservice/repository/TakeOutOrderRepository.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import takeout.waiterservice.model.TakeOutOrder;
5 |
6 | import java.util.List;
7 |
8 | public interface TakeOutOrderRepository extends JpaRepository {
9 | List findByCustomerOrderById(String customer);
10 | }
11 |
--------------------------------------------------------------------------------
/section-11/waiter-service/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | prefix.name: Jarvis
2 |
3 | server.port: 8080
4 |
5 | management.endpoints.web.exposure.include:
6 | - health
7 | - refresh
8 |
9 | spring:
10 | output.ansi.enabled: ALWAYS
11 |
12 | rabbitmq:
13 | host: rabbit
14 | port: 5672
15 | username: guest
16 | password: guest
17 |
18 | cloud:
19 | stream:
20 | bindings:
21 | default.binder: rabbit
22 | finishedOrders.group: waiter-service
23 | binders.rabbit.type: rabbit
24 | zookeeper.discovery.preferIpAddress: true
25 | inetutils:
26 | ignoredInterfaces:
27 | - docker0
28 | - veth.*
29 |
30 | sleth.sampler.probability: 1.0
31 |
32 | zipkin:
33 | baseUrl: http://zipkin:9411
34 | sender.type: web
35 |
--------------------------------------------------------------------------------
/section-11/waiter-service/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application.name: waiter-service
3 |
4 | cloud.zookeeper:
5 | config.enabled: true
6 | connect-string: zookeeper:2181
7 |
--------------------------------------------------------------------------------
/section-11/waiter-service/src/test/java/takeout/waiterservice/WaiterServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class WaiterServiceApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-12/README.md:
--------------------------------------------------------------------------------
1 | # Section 12
2 |
3 | 在Kubernetes上运行一个简单的TakeOut示例。
4 |
5 | * 基于Section 06修改代码,去除Spring Cloud相关内容,简化部分代码
6 | * 修改程序配置,适应k8s容器环境
7 | * 修改Docker打包相关配置,将镜像上传至阿里云的私有镜像
8 | * 增加用于本地minikube和阿里云k8s的部署文件
9 |
10 | 执行命令打包:
11 | ```
12 | mvn clean package docker:build -Dmaven.test.skip
13 | ```
14 |
15 | 在minikube中执行部署命令:
16 | ```
17 | kubectl create -f takeout-minikube.yml
18 | ```
19 |
20 | 部署到阿里云(需要事先在k8s上配置私有镜像的secret):
21 | ```
22 | kubectl create -f takeout-aliyun.yml
23 | ```
24 |
25 | 在阿里云上如果部署了Istio,先设置自动注入SideCar:
26 |
27 | ```
28 | kubectl label namespace default istio-injection=enabled
29 | ```
30 |
31 | 在`istio`目录中有一些Istio的演示,先运行`kubectl create -f istio-destination.yml`创建Destination,随后再运行其他的Yaml。
32 |
33 | 可以用下面的命令开启Grafana,观察服务的调用情况:
34 | ```
35 | kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana -o jsonpath='{.items[0].metadata.name}') 3000:3000 &
36 | ```
37 |
--------------------------------------------------------------------------------
/section-12/customer-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-12/customer-service/src/main/docker/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM java:8
2 | EXPOSE 7080
3 | ADD customer-service-0.0.1-SNAPSHOT.jar customer-service.jar
4 | ENTRYPOINT ["java", "-jar","/customer-service.jar"]
--------------------------------------------------------------------------------
/section-12/customer-service/src/main/java/takeout/customerservice/CustomerServiceApplication.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.beans.factory.annotation.Value;
6 | import org.springframework.boot.SpringApplication;
7 | import org.springframework.boot.autoconfigure.SpringBootApplication;
8 | import org.springframework.context.annotation.Bean;
9 | import org.springframework.core.ParameterizedTypeReference;
10 | import org.springframework.http.HttpMethod;
11 | import org.springframework.http.ResponseEntity;
12 | import org.springframework.web.bind.annotation.PostMapping;
13 | import org.springframework.web.bind.annotation.RestController;
14 | import org.springframework.web.client.RestTemplate;
15 | import org.springframework.web.util.UriComponentsBuilder;
16 | import takeout.customerservice.model.Order;
17 | import takeout.customerservice.model.Payment;
18 |
19 | import java.net.URI;
20 | import java.util.List;
21 |
22 | @SpringBootApplication
23 | @RestController
24 | @Slf4j
25 | public class CustomerServiceApplication {
26 | @Autowired
27 | private RestTemplate restTemplate;
28 | @Value("${waiter.url}")
29 | private String waiterUrl;
30 | @Value("${customer.name}-${random.int}")
31 | private String customer;
32 |
33 | public static void main(String[] args) {
34 | SpringApplication.run(CustomerServiceApplication.class, args);
35 | }
36 |
37 | @Bean
38 | public RestTemplate restTemplate() {
39 | return new RestTemplate();
40 | }
41 |
42 | @PostMapping("/orders")
43 | public Order createNewOrder() {
44 | URI uri = UriComponentsBuilder.fromHttpUrl(waiterUrl + "/orders").build().toUri();
45 | Order rawOrder = Order.builder().customer(customer).items("Coffee").price(2000L).build();
46 |
47 | List orders = restTemplate.exchange(uri, HttpMethod.GET, null,
48 | new ParameterizedTypeReference>() {}).getBody();
49 | log.info("There are {} orders ahead.", orders.size());
50 |
51 | Order order = restTemplate.postForObject(uri, rawOrder, Order.class);
52 | log.info("Order created: {}", order);
53 |
54 | return order;
55 | }
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/section-12/customer-service/src/main/java/takeout/customerservice/model/Order.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice.model;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @NoArgsConstructor
10 | @AllArgsConstructor
11 | @Builder
12 | public class Order {
13 | private Long id;
14 | private String items;
15 | private String customer;
16 | private String waiter;
17 | private Long price;
18 | private String state;
19 | }
20 |
--------------------------------------------------------------------------------
/section-12/customer-service/src/main/java/takeout/customerservice/model/Payment.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice.model;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | @Data
9 | @AllArgsConstructor
10 | @NoArgsConstructor
11 | @Builder
12 | public class Payment {
13 | private Long id;
14 | private Long orderId;
15 | private Long price;
16 | private String state;
17 | }
18 |
--------------------------------------------------------------------------------
/section-12/customer-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | customer.name=Natasha
2 | waiter.url=http://${WAITER_SERVICE_HOST}:${WAITER_SERVICE_PORT}
3 |
4 | server.port=7080
5 | spring.output.ansi.enabled=ALWAYS
6 |
--------------------------------------------------------------------------------
/section-12/customer-service/src/test/java/takeout/customerservice/CustomerServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.customerservice;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class CustomerServiceApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/section-12/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | customer-service:
5 | image: registry.cn-huhehaote.aliyuncs.com/digitalsonic/customer-service
6 | environment:
7 | - WAITER_URL=http://waiter-service:8080
8 | expose:
9 | - "7080"
10 | ports:
11 | - "7080:7080"
12 | depends_on:
13 | - waiter-service
14 | links:
15 | - waiter-service
16 |
17 | waiter-service:
18 | image: registry.cn-huhehaote.aliyuncs.com/digitalsonic/waiter-service
19 | expose:
20 | - "8080"
21 |
--------------------------------------------------------------------------------
/section-12/istio/istio-destination.yml:
--------------------------------------------------------------------------------
1 | apiVersion: networking.istio.io/v1alpha3
2 | kind: DestinationRule
3 | metadata:
4 | name: customer
5 | spec:
6 | host: customer
7 | subsets:
8 | - name: v1
9 | labels:
10 | version: v1
11 | ---
12 | apiVersion: networking.istio.io/v1alpha3
13 | kind: DestinationRule
14 | metadata:
15 | name: waiter
16 | spec:
17 | host: waiter
18 | subsets:
19 | - name: v1
20 | labels:
21 | version: v1
22 | - name: v2
23 | labels:
24 | version: v2
25 |
--------------------------------------------------------------------------------
/section-12/istio/istio-vs-all-v1.yml:
--------------------------------------------------------------------------------
1 | apiVersion: networking.istio.io/v1alpha3
2 | kind: VirtualService
3 | metadata:
4 | name: customer
5 | spec:
6 | hosts:
7 | - customer
8 | http:
9 | - route:
10 | - destination:
11 | host: customer
12 | ---
13 | apiVersion: networking.istio.io/v1alpha3
14 | kind: VirtualService
15 | metadata:
16 | name: waiter
17 | spec:
18 | hosts:
19 | - waiter
20 | http:
21 | - route:
22 | - destination:
23 | host: waiter
24 | subset: v1
25 |
--------------------------------------------------------------------------------
/section-12/istio/istio-vs-waiter-abort.yml:
--------------------------------------------------------------------------------
1 | apiVersion: networking.istio.io/v1alpha3
2 | kind: VirtualService
3 | metadata:
4 | name: customer
5 | spec:
6 | hosts:
7 | - customer
8 | http:
9 | - route:
10 | - destination:
11 | host: customer
12 | ---
13 | apiVersion: networking.istio.io/v1alpha3
14 | kind: VirtualService
15 | metadata:
16 | name: waiter
17 | spec:
18 | hosts:
19 | - waiter
20 | http:
21 | - route:
22 | - destination:
23 | host: waiter
24 | subset: v1
25 | weight: 50
26 | - destination:
27 | host: waiter
28 | subset: v2
29 | weight: 50
30 | fault:
31 | abort:
32 | percent: 10
33 | httpStatus: 500
--------------------------------------------------------------------------------
/section-12/istio/istio-vs-waiter-delay.yml:
--------------------------------------------------------------------------------
1 | apiVersion: networking.istio.io/v1alpha3
2 | kind: VirtualService
3 | metadata:
4 | name: customer
5 | spec:
6 | hosts:
7 | - customer
8 | http:
9 | - route:
10 | - destination:
11 | host: customer
12 | ---
13 | apiVersion: networking.istio.io/v1alpha3
14 | kind: VirtualService
15 | metadata:
16 | name: waiter
17 | spec:
18 | hosts:
19 | - waiter
20 | http:
21 | - route:
22 | - destination:
23 | host: waiter
24 | subset: v1
25 | weight: 50
26 | - destination:
27 | host: waiter
28 | subset: v2
29 | weight: 50
30 | fault:
31 | delay:
32 | percent: 10
33 | fixedDelay: 5s
--------------------------------------------------------------------------------
/section-12/istio/istio-vs-waiter-percent.yml:
--------------------------------------------------------------------------------
1 | apiVersion: networking.istio.io/v1alpha3
2 | kind: VirtualService
3 | metadata:
4 | name: customer
5 | spec:
6 | hosts:
7 | - customer
8 | http:
9 | - route:
10 | - destination:
11 | host: customer
12 | ---
13 | apiVersion: networking.istio.io/v1alpha3
14 | kind: VirtualService
15 | metadata:
16 | name: waiter
17 | spec:
18 | hosts:
19 | - waiter
20 | http:
21 | - route:
22 | - destination:
23 | host: waiter
24 | subset: v1
25 | weight: 10
26 | - destination:
27 | host: waiter
28 | subset: v2
29 | weight: 90
30 |
--------------------------------------------------------------------------------
/section-12/istio/istio-vs-waiter-v2.yml:
--------------------------------------------------------------------------------
1 | apiVersion: networking.istio.io/v1alpha3
2 | kind: VirtualService
3 | metadata:
4 | name: customer
5 | spec:
6 | hosts:
7 | - customer
8 | http:
9 | - route:
10 | - destination:
11 | host: customer
12 | ---
13 | apiVersion: networking.istio.io/v1alpha3
14 | kind: VirtualService
15 | metadata:
16 | name: waiter
17 | spec:
18 | hosts:
19 | - waiter
20 | http:
21 | - route:
22 | - destination:
23 | host: waiter
24 | subset: v2
25 |
--------------------------------------------------------------------------------
/section-12/takeout-aliyun.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: waiter
5 | spec:
6 | selector:
7 | app: waiter-service
8 | ports:
9 | - name: http
10 | port: 8080
11 | ---
12 | apiVersion: extensions/v1beta1
13 | kind: Deployment
14 | metadata:
15 | name: waiter-service-v1
16 | spec:
17 | replicas: 1
18 | template:
19 | metadata:
20 | labels:
21 | app: waiter-service
22 | version: v1
23 | spec:
24 | containers:
25 | - name: waiter-service
26 | image: registry-vpc.cn-huhehaote.aliyuncs.com/digitalsonic/waiter-service
27 | imagePullPolicy: IfNotPresent
28 | ports:
29 | - containerPort: 8080
30 | env:
31 | - name: WAITER_NAME
32 | value: "Mark I"
33 | imagePullSecrets:
34 | - name: digitalsonic
35 | ---
36 | apiVersion: extensions/v1beta1
37 | kind: Deployment
38 | metadata:
39 | name: waiter-service-v2
40 | spec:
41 | replicas: 1
42 | template:
43 | metadata:
44 | labels:
45 | app: waiter-service
46 | version: v2
47 | spec:
48 | containers:
49 | - name: waiter-service
50 | image: registry-vpc.cn-huhehaote.aliyuncs.com/digitalsonic/waiter-service
51 | imagePullPolicy: IfNotPresent
52 | ports:
53 | - containerPort: 8080
54 | env:
55 | - name: WAITER_NAME
56 | value: "Mark II"
57 | imagePullSecrets:
58 | - name: digitalsonic
59 | ---
60 | apiVersion: v1
61 | kind: Service
62 | metadata:
63 | name: customer
64 | spec:
65 | selector:
66 | app: customer-service
67 | ports:
68 | - name: http
69 | port: 7080
70 | ---
71 | apiVersion: extensions/v1beta1
72 | kind: Deployment
73 | metadata:
74 | name: customer-service
75 | spec:
76 | replicas: 1
77 | template:
78 | metadata:
79 | labels:
80 | app: customer-service
81 | version: v1
82 | spec:
83 | containers:
84 | - name: customer-service
85 | image: registry-vpc.cn-huhehaote.aliyuncs.com/digitalsonic/customer-service
86 | imagePullPolicy: IfNotPresent
87 | ports:
88 | - containerPort: 7080
89 | imagePullSecrets:
90 | - name: digitalsonic
91 |
92 |
--------------------------------------------------------------------------------
/section-12/takeout-minikube.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: waiter
5 | spec:
6 | selector:
7 | app: waiter-service
8 | ports:
9 | - name: http
10 | port: 8080
11 | ---
12 | apiVersion: extensions/v1beta1
13 | kind: Deployment
14 | metadata:
15 | name: waiter-service-v1
16 | spec:
17 | replicas: 1
18 | template:
19 | metadata:
20 | labels:
21 | app: waiter-service
22 | version: v1
23 | spec:
24 | containers:
25 | - name: waiter-service
26 | image: registry.cn-huhehaote.aliyuncs.com/digitalsonic/waiter-service
27 | imagePullPolicy: IfNotPresent
28 | ports:
29 | - containerPort: 8080
30 | env:
31 | - name: WAITER_NAME
32 | value: "Mark I"
33 | ---
34 | apiVersion: extensions/v1beta1
35 | kind: Deployment
36 | metadata:
37 | name: waiter-service-v2
38 | spec:
39 | replicas: 1
40 | template:
41 | metadata:
42 | labels:
43 | app: waiter-service
44 | version: v2
45 | spec:
46 | containers:
47 | - name: waiter-service
48 | image: registry.cn-huhehaote.aliyuncs.com/digitalsonic/waiter-service
49 | imagePullPolicy: IfNotPresent
50 | ports:
51 | - containerPort: 8080
52 | env:
53 | - name: WAITER_NAME
54 | value: "Mark II"
55 | ---
56 | apiVersion: v1
57 | kind: Service
58 | metadata:
59 | name: customer
60 | spec:
61 | selector:
62 | app: customer-service
63 | type: NodePort
64 | ports:
65 | - name: http
66 | port: 7080
67 | ---
68 | apiVersion: extensions/v1beta1
69 | kind: Deployment
70 | metadata:
71 | name: customer-service
72 | spec:
73 | replicas: 1
74 | template:
75 | metadata:
76 | labels:
77 | app: customer-service
78 | version: v1
79 | spec:
80 | containers:
81 | - name: customer-service
82 | image: registry.cn-huhehaote.aliyuncs.com/digitalsonic/customer-service
83 | imagePullPolicy: IfNotPresent
84 | ports:
85 | - containerPort: 7080
86 |
--------------------------------------------------------------------------------
/section-12/waiter-service/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 | .sts4-cache
12 |
13 | ### IntelliJ IDEA ###
14 | .idea
15 | *.iws
16 | *.iml
17 | *.ipr
18 |
19 | ### NetBeans ###
20 | /nbproject/private/
21 | /build/
22 | /nbbuild/
23 | /dist/
24 | /nbdist/
25 | /.nb-gradle/
--------------------------------------------------------------------------------
/section-12/waiter-service/src/main/docker/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM java:8
2 | EXPOSE 8080
3 | ADD waiter-service-0.0.1-SNAPSHOT.jar waiter-service.jar
4 | ENTRYPOINT ["java", "-jar","/waiter-service.jar"]
--------------------------------------------------------------------------------
/section-12/waiter-service/src/main/java/takeout/waiterservice/WaiterServiceApplication.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class WaiterServiceApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(WaiterServiceApplication.class, args);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/section-12/waiter-service/src/main/java/takeout/waiterservice/controller/ExceptionControllerAdvice.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.http.HttpStatus;
4 | import org.springframework.web.bind.annotation.ControllerAdvice;
5 | import org.springframework.web.bind.annotation.ExceptionHandler;
6 | import org.springframework.web.bind.annotation.ResponseStatus;
7 |
8 | import javax.persistence.EntityNotFoundException;
9 | import java.util.Collections;
10 | import java.util.Map;
11 |
12 | @ControllerAdvice
13 | public class ExceptionControllerAdvice {
14 | @ExceptionHandler(EntityNotFoundException.class)
15 | @ResponseStatus(HttpStatus.NOT_FOUND)
16 | public Map entityNotFound(EntityNotFoundException e) {
17 | return Collections.singletonMap("message", e.getMessage());
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/section-12/waiter-service/src/main/java/takeout/waiterservice/controller/OrderController.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.web.bind.annotation.DeleteMapping;
6 | import org.springframework.web.bind.annotation.GetMapping;
7 | import org.springframework.web.bind.annotation.PathVariable;
8 | import org.springframework.web.bind.annotation.PostMapping;
9 | import org.springframework.web.bind.annotation.RequestBody;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.ResponseStatus;
12 | import org.springframework.web.bind.annotation.RestController;
13 | import takeout.waiterservice.model.TakeOutOrder;
14 | import takeout.waiterservice.service.OrderService;
15 |
16 | import java.util.List;
17 |
18 | @RestController
19 | @RequestMapping("/orders")
20 | public class OrderController {
21 | @Autowired
22 | private OrderService orderService;
23 |
24 | @GetMapping("/{id}")
25 | public TakeOutOrder getOrder(@PathVariable Long id) {
26 | return orderService.getOrder(id);
27 | }
28 |
29 | @DeleteMapping("/{id}")
30 | public List deleteOrder(@PathVariable Long id) {
31 | orderService.deleteOrder(id);
32 | return orderService.getAllOrders();
33 | }
34 |
35 | @PostMapping
36 | @ResponseStatus(HttpStatus.CREATED)
37 | public TakeOutOrder createOrder(@RequestBody TakeOutOrder order) {
38 | return orderService.createOrder(order);
39 | }
40 |
41 | @GetMapping
42 | public List getAllOrder() {
43 | return orderService.getAllOrders();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/section-12/waiter-service/src/main/java/takeout/waiterservice/controller/PaymentController.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.web.bind.annotation.PathVariable;
6 | import org.springframework.web.bind.annotation.RequestBody;
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 | import org.springframework.web.bind.annotation.RestController;
11 | import takeout.waiterservice.model.Payment;
12 | import takeout.waiterservice.service.PaymentService;
13 |
14 | @RestController
15 | @RequestMapping("/orders/{id}/payment")
16 | public class PaymentController {
17 | @Autowired
18 | private PaymentService paymentService;
19 |
20 | @RequestMapping(method = RequestMethod.POST)
21 | @ResponseStatus(HttpStatus.CREATED)
22 | public Payment createPayment(@PathVariable Long id) {
23 | return paymentService.createPayment(id);
24 | }
25 |
26 | @RequestMapping(method = RequestMethod.GET)
27 | public Payment getPayment(@PathVariable Long id) {
28 | return paymentService.getPayment(id);
29 | }
30 |
31 | @RequestMapping(method = RequestMethod.PUT)
32 | public Payment updatePayment(@PathVariable Long id, @RequestBody Payment payment) {
33 | return paymentService.updatePayment(id, payment);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/section-12/waiter-service/src/main/java/takeout/waiterservice/model/Payment.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import javax.persistence.Column;
10 | import javax.persistence.Entity;
11 | import javax.persistence.GeneratedValue;
12 | import javax.persistence.Id;
13 | import javax.xml.bind.annotation.XmlRootElement;
14 | import java.util.Date;
15 |
16 | @Entity
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Builder
21 | @XmlRootElement
22 | public class Payment {
23 | @Id
24 | @GeneratedValue
25 | private Long id;
26 | @Column(updatable = false)
27 | private Long orderId;
28 | private Long price;
29 | private String state;
30 | @Column(updatable = false)
31 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
32 | private Date createTime;
33 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
34 | private Date modifyTime;
35 | }
36 |
--------------------------------------------------------------------------------
/section-12/waiter-service/src/main/java/takeout/waiterservice/model/TakeOutOrder.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | import javax.persistence.Column;
11 | import javax.persistence.Entity;
12 | import javax.persistence.GeneratedValue;
13 | import javax.persistence.Id;
14 | import javax.xml.bind.annotation.XmlRootElement;
15 | import java.util.Date;
16 |
17 | @Data
18 | @NoArgsConstructor
19 | @AllArgsConstructor
20 | @Builder
21 | @JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler", "fieldHandler"})
22 | @Entity
23 | @XmlRootElement
24 | public class TakeOutOrder {
25 | @Id
26 | @GeneratedValue
27 | private Long id;
28 | private String items;
29 | private String customer;
30 | private String waiter;
31 | private Long price;
32 | private String state;
33 | @Column(updatable = false)
34 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
35 | private Date createTime;
36 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
37 | private Date modifyTime;
38 | }
39 |
--------------------------------------------------------------------------------
/section-12/waiter-service/src/main/java/takeout/waiterservice/repository/PaymentRepository.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import takeout.waiterservice.model.Payment;
5 |
6 | import java.util.Optional;
7 |
8 | public interface PaymentRepository extends JpaRepository {
9 | Optional findByOrderId(Long orderId);
10 | }
11 |
--------------------------------------------------------------------------------
/section-12/waiter-service/src/main/java/takeout/waiterservice/repository/TakeOutOrderRepository.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import takeout.waiterservice.model.TakeOutOrder;
5 |
6 | import java.util.List;
7 |
8 | public interface TakeOutOrderRepository extends JpaRepository {
9 | List findByCustomerOrderById(String customer);
10 | }
11 |
--------------------------------------------------------------------------------
/section-12/waiter-service/src/main/java/takeout/waiterservice/service/OrderService.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice.service;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.beans.factory.annotation.Value;
5 | import org.springframework.stereotype.Service;
6 | import takeout.waiterservice.model.TakeOutOrder;
7 | import takeout.waiterservice.repository.TakeOutOrderRepository;
8 |
9 | import javax.persistence.EntityNotFoundException;
10 | import java.util.Date;
11 | import java.util.List;
12 |
13 | @Service
14 | public class OrderService {
15 | @Autowired
16 | private TakeOutOrderRepository orderRepository;
17 | @Value("${waiter.name}-${random.int}")
18 | private String waiterName;
19 |
20 | public List getAllOrders() {
21 | return orderRepository.findAll();
22 | }
23 |
24 | public TakeOutOrder getOrder(Long id) {
25 | return id == null ? null : orderRepository.findById(id)
26 | .orElseThrow(() -> new EntityNotFoundException("Order " + id + " is NOT found."));
27 | }
28 |
29 | public void deleteOrder(Long id) {
30 | orderRepository.delete(
31 | orderRepository.findById(id)
32 | .orElseThrow(() -> new EntityNotFoundException("Order " + id + " is NOT found."))
33 | );
34 | }
35 |
36 | public TakeOutOrder createOrder(TakeOutOrder order) {
37 | if (order != null) {
38 | order.setId(null);
39 | order.setWaiter(waiterName);
40 | order.setState("I");
41 | order.setCreateTime(new Date());
42 | order.setModifyTime(new Date());
43 | orderRepository.save(order);
44 | }
45 | return order;
46 | }
47 |
48 | public void payOrder(Long id) {
49 | TakeOutOrder order = orderRepository.getOne(id);
50 | order.setState("P");
51 | order.setModifyTime(new Date());
52 | orderRepository.save(order);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/section-12/waiter-service/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.output.ansi.enabled=ALWAYS
2 | waiter.name=Tony
--------------------------------------------------------------------------------
/section-12/waiter-service/src/test/java/takeout/waiterservice/WaiterServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package takeout.waiterservice;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class WaiterServiceApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------