This is an automated email from the ASF dual-hosted git repository. ningjiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-saga.git
commit 534ad26d223c9faed41600c504abb802a7074b35 Author: imlijinting <[email protected]> AuthorDate: Mon Sep 3 00:19:42 2018 +0800 [SCB-820] Added Tcc Demo --- saga-demo/pom.xml | 1 + saga-demo/tcc-spring-demo/README.md | 145 +++++++++++++++++++++ .../tcc-spring-demo/docker-compose-alpha.yaml | 48 +++++++ saga-demo/tcc-spring-demo/docker-compose-demo.yaml | 48 +++++++ .../tcc-spring-demo/docker-compose.mysql.yaml | 39 ++++++ saga-demo/tcc-spring-demo/docker-compose.yaml | 83 ++++++++++++ saga-demo/tcc-spring-demo/inventory/pom.xml | 112 ++++++++++++++++ .../saga/demo/pack/inventory/InventoryService.java | 54 ++++++++ .../saga/demo/pack/inventory/Product.java | 85 ++++++++++++ .../demo/pack/inventory/ProductController.java | 75 +++++++++++ .../saga/demo/pack/inventory/ProductDao.java | 7 + .../pack/inventory/TccInventoryApplication.java | 40 ++++++ .../inventory/src/main/resources/application.yaml | 37 ++++++ .../inventory/src/main/resources/log4j2.xml | 30 +++++ .../demo/pack/inventory/InventoryServiceTest.java | 28 ++++ .../inventory/src/test/resources/application.yaml | 37 ++++++ saga-demo/tcc-spring-demo/ordering/pom.xml | 108 +++++++++++++++ .../demo/pack/ordering/OrderingController.java | 26 ++++ .../demo/pack/ordering/TccOrderingApplication.java | 30 +++++ .../ordering/src/main/resources/application.yaml | 29 +++++ .../ordering/src/main/resources/log4j2.xml | 30 +++++ .../ordering/src/main/resources/static/index.html | 91 +++++++++++++ saga-demo/tcc-spring-demo/payment/pom.xml | 106 +++++++++++++++ .../demo/pack/payment/TccPaymentApplication.java | 30 +++++ .../payment/src/main/resources/application.yaml | 29 +++++ .../payment/src/main/resources/log4j2.xml | 30 +++++ saga-demo/tcc-spring-demo/pom.xml | 47 +++++++ saga-demo/tcc-spring-demo/saga-demo.sh | 74 +++++++++++ 28 files changed, 1499 insertions(+) diff --git a/saga-demo/pom.xml b/saga-demo/pom.xml index cff708a..614dfa6 100644 --- a/saga-demo/pom.xml +++ b/saga-demo/pom.xml @@ -35,6 +35,7 @@ <module>saga-servicecomb-demo</module> <module>dependency-free-transaction-demo</module> <module>conditional-transaction-demo</module> + <module>tcc-spring-demo</module> </modules> <dependencyManagement> diff --git a/saga-demo/tcc-spring-demo/README.md b/saga-demo/tcc-spring-demo/README.md new file mode 100644 index 0000000..0502493 --- /dev/null +++ b/saga-demo/tcc-spring-demo/README.md @@ -0,0 +1,145 @@ +# Booking Demo +This demo simulates a booking application including three services: +* booking +* car +* hotel + +## Prerequisites +You will need: +1. [JDK 1.8][jdk] +2. [Maven 3.x][maven] +3. [Docker][docker] +4. [Docker compose][docker_compose] +5. [alpha server][alpha_server] + +[jdk]: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html +[maven]: https://maven.apache.org/install.html +[docker]: https://www.docker.com/get-docker +[docker_compose]: https://docs.docker.com/compose/install/ +[alpha_server]: https://github.com/apache/incubator-servicecomb-saga/tree/master/alpha + +## Running Demo +You can run the demo using either docker compose or executable files. +### via docker compose +1. run the following command to create docker images in saga project root folder. + ``` + mvn clean package -DskipTests -Pdocker -Pdemo + ``` + +2. start the whole application up(including alpha server and three demo services) + ``` + ./saga-demo.sh up + ``` + + **Note:** If you prefer to use MySQL as alpha's backend database, you need to try the following steps instead: + 1. add dependency of `mysql-connector-java` in `alpha/alpha-server/pom.xml` + ```xml + <dependency> + <groupId>mysql</groupId> + <artifactId>mysql-connector-java</artifactId> + </dependency> + ``` + 2. remove alpha server's docker image + ```bash + docker rmi -f $(docker images | grep alpha-server | awk '{print $3}') + ``` + 3. re-generate saga's docker images + ```bash + mvn package -DskipTests -Pdocker -Pdemo + ``` + 4. start application up in `saga-demo/booking` with the following command + ``` + ./saga-demo.sh up-mysql + ``` + + **Note:** If you want start alpha server and demon services separately, you can try the following steps: + 1. start alpha server + ```bash + ./saga-demo.sh up-alpha + ``` + 2. when alpha server started complatelly, then start the demo services + ```bash + ./saga-demo.sh up-demo + ``` + +3. stop application + ``` + ./saga-demo.sh down + ``` + +### via executable files +1. run the following command to generate executable alpha server jar in `alpha/alpha-server/target/saga/alpha-server-${saga_version}-exec.jar`. + ``` + mvn clean package -DskipTests -Pdemo + ``` + +2. follow the instructions in the [How to run](https://github.com/apache/incubator-servicecomb-saga/blob/master/docs/user_guide.md#how-to-run) section in User Guide to run postgreSQL and alpha server. + +3. start application up + 1. start hotel service. The executable jar file should be in `saga-demo/booking/hotel/target/saga`. + ```bash + java -Dserver.port=8081 -Dalpha.cluster.address=${alpha_address}:8080 -jar hotel-${saga_version}-exec.jar + ``` + + 2. start car service. The executable jar file should be in `saga-demo/booking/car/target/saga`. + ```bash + java -Dserver.port=8082 -Dalpha.cluster.address=${alpha_address}:8080 -jar car-${saga_version}-exec.jar + ``` + + 3. start booking service. The executable jar file should be in `saga-demo/booking/booking/target/saga`. + ```bash + java -Dserver.port=8083 -Dalpha.cluster.address=${alpha_address}:8080 -Dcar.service.address=${host_address}:8082 -Dhotel.service.address=${host_address}:8081 -jar booking-${saga_version}-exec.jar + ``` + +## User Requests by command line tools +1. Booking 2 rooms and 2 cars, this booking will be OK. +``` +curl -X POST http://${host_address}:8083/booking/test/2/2 +``` +Check the hotel booking status with +``` +curl http://${host_address}:8081/bookings +``` +Check the car booking status with +``` +curl http://${host_address}:8082/bookings + +``` + +2. Booking 3 rooms and 2 cars, this booking will cause the hotel order failed and trigger the compensate operation with car booking. +``` +curl -X POST http://${host_address}:8083/booking/test/3/2 +``` +Check the hotel booking status with +``` +curl http://${host_address}:8081/bookings +``` +Check the car booking status with +``` +curl http://${host_address}:8082/bookings +``` +The second car booking will be marked with **cancel:true** + +## User Requests by html page + +Open a browser with URL http://127.0.0.1:8083, You will get a html page. You can use this page to invoke test cases, and then get results. + +**Note** transactions and compensations implemented by services must be idempotent. + +## Debugging + +To debug the services of the demo, just add debug parameter to JVM through the environment field in docker-compose configs. Let's take alpha-server as an example: + +```yaml +alpha: + image: "alpha-server:${TAG}" + environment: + - JAVA_OPTS=-Dspring.profiles.active=prd -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 + ports: + - "6006:5005" +... +``` + +We append the debug parameter `-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005` to the JAVA_OPTS environment variable, the Java process inside the container will listen on port 5005. With the port forwarding rule `6006:5005`, when alpha-server is ready, we can connect to port 6006 on the host and start debugging alpha-server. + +If you're using [IntelliJ](https://www.jetbrains.com/idea/), open the saga project, create a new debug configuration with template 'Remote', fill "Host" and "Port" input with "localhost" and "6006", then select "alpha" in the drop-down list of "Use classpath of module". When alpha-server is running, hit shift+f9 to debug the remote application. diff --git a/saga-demo/tcc-spring-demo/docker-compose-alpha.yaml b/saga-demo/tcc-spring-demo/docker-compose-alpha.yaml new file mode 100644 index 0000000..a664c23 --- /dev/null +++ b/saga-demo/tcc-spring-demo/docker-compose-alpha.yaml @@ -0,0 +1,48 @@ +## --------------------------------------------------------------------------- +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); you may not use this file except in compliance with +## the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## --------------------------------------------------------------------------- + +version: '2.1' + +services: + database: + image: "postgres" + hostname: postgres + environment: + - POSTGRES_DB=saga + - POSTGRES_USER=saga + - POSTGRES_PASSWORD=password + healthcheck: + test: ["CMD-SHELL", "nc -z localhost 5432 &> /dev/null; echo $$?"] + interval: 30s + timeout: 10s + retries: 5 + + alpha: + image: "alpha-server:${TAG}" + hostname: alpha-server + links: + - "database:postgresql.servicecomb.io" + environment: + - JAVA_OPTS=-Dspring.profiles.active=prd + healthcheck: + test: ["CMD-SHELL", "nc -z localhost 8080 &> /dev/null; echo $$?"] + interval: 30s + timeout: 10s + retries: 5 + depends_on: + database: + condition: service_healthy diff --git a/saga-demo/tcc-spring-demo/docker-compose-demo.yaml b/saga-demo/tcc-spring-demo/docker-compose-demo.yaml new file mode 100644 index 0000000..2fcf1a1 --- /dev/null +++ b/saga-demo/tcc-spring-demo/docker-compose-demo.yaml @@ -0,0 +1,48 @@ +## --------------------------------------------------------------------------- +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); you may not use this file except in compliance with +## the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## --------------------------------------------------------------------------- + +version: '2.1' + +services: + hotel: + image: "hotel:${TAG}" + hostname: hotel + external_links: + - "alpha:alpha-server.servicecomb.io" + ports: + - "8081:8080" + + car: + image: "car:${TAG}" + hostname: car + external_links: + - "alpha:alpha-server.servicecomb.io" + ports: + - "8082:8080" + + booking: + image: "booking:${TAG}" + hostname: booking + external_links: + - "alpha:alpha-server.servicecomb.io" + - "hotel:hotel.servicecomb.io" + - "car:car.servicecomb.io" + ports: + - "8083:8080" + depends_on: + - hotel + - car diff --git a/saga-demo/tcc-spring-demo/docker-compose.mysql.yaml b/saga-demo/tcc-spring-demo/docker-compose.mysql.yaml new file mode 100644 index 0000000..43f3b5e --- /dev/null +++ b/saga-demo/tcc-spring-demo/docker-compose.mysql.yaml @@ -0,0 +1,39 @@ +## --------------------------------------------------------------------------- +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); you may not use this file except in compliance with +## the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## --------------------------------------------------------------------------- + +version: '2.1' + +services: + database: + image: "mysql/mysql-server:5.7" + hostname: mysql + environment: + - MYSQL_ROOT_PASSWORD=password + - MYSQL_DATABASE=saga + - MYSQL_USER=saga + - MYSQL_PASSWORD=password + healthcheck: + test: ["CMD-SHELL", "nc -z localhost 3306 &> /dev/null; echo $$?"] + interval: 30s + timeout: 10s + retries: 5 + + alpha: + links: + - "database:mysql.servicecomb.io" + environment: + - JAVA_OPTS=-Dspring.profiles.active=mysql diff --git a/saga-demo/tcc-spring-demo/docker-compose.yaml b/saga-demo/tcc-spring-demo/docker-compose.yaml new file mode 100644 index 0000000..38e48f1 --- /dev/null +++ b/saga-demo/tcc-spring-demo/docker-compose.yaml @@ -0,0 +1,83 @@ +## --------------------------------------------------------------------------- +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); you may not use this file except in compliance with +## the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## --------------------------------------------------------------------------- + +version: '2.1' + +services: + database: + image: "postgres" + hostname: postgres + environment: + - POSTGRES_DB=saga + - POSTGRES_USER=saga + - POSTGRES_PASSWORD=password + healthcheck: + test: ["CMD-SHELL", "nc -z localhost 5432 &> /dev/null; echo $$?"] + interval: 30s + timeout: 10s + retries: 5 + + alpha: + image: "alpha-server:${TAG}" + hostname: alpha-server + links: + - "database:postgresql.servicecomb.io" + environment: + - JAVA_OPTS=-Dspring.profiles.active=prd + healthcheck: + test: ["CMD-SHELL", "nc -z localhost 8080 &> /dev/null; echo $$?"] + interval: 30s + timeout: 10s + retries: 5 + depends_on: + database: + condition: service_healthy + + hotel: + image: "hotel:${TAG}" + hostname: hotel + links: + - "alpha:alpha-server.servicecomb.io" + ports: + - "8081:8080" + depends_on: + alpha: + condition: service_healthy + + car: + image: "car:${TAG}" + hostname: car + links: + - "alpha:alpha-server.servicecomb.io" + ports: + - "8082:8080" + depends_on: + alpha: + condition: service_healthy + + booking: + image: "booking:${TAG}" + hostname: booking + links: + - "alpha:alpha-server.servicecomb.io" + - "hotel:hotel.servicecomb.io" + - "car:car.servicecomb.io" + ports: + - "8083:8080" + depends_on: + - hotel + - car diff --git a/saga-demo/tcc-spring-demo/inventory/pom.xml b/saga-demo/tcc-spring-demo/inventory/pom.xml new file mode 100644 index 0000000..aed29e4 --- /dev/null +++ b/saga-demo/tcc-spring-demo/inventory/pom.xml @@ -0,0 +1,112 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>saga-spring-demo</artifactId> + <groupId>org.apache.servicecomb.saga.demo</groupId> + <version>0.3.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>Tcc-Inventory</artifactId> + <name>Saga::Demo::Tcc-Spring-Demo::Tcc-Inventory</name> + + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + </dependency> + <dependency> + <groupId>org.apache.servicecomb.saga</groupId> + <artifactId>omega-spring-starter</artifactId> + </dependency> + <dependency> + <groupId>org.apache.servicecomb.saga</groupId> + <artifactId>omega-transport-resttemplate</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-data-jpa</artifactId> + </dependency> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + </dependency> + <dependency> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <!-- mixin plugin configurations declared in another pom, + just like importing dependencies managed in another pom --> + <plugin> + <groupId>com.github.odavid.maven.plugins</groupId> + <artifactId>mixin-maven-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + </plugin> + </plugins> + </build> + + <profiles> + <profile> + <id>docker</id> + <activation> + <file> + <exists>/var/run/docker.sock</exists> + </file> + </activation> + <build> + <plugins> + <plugin> + <groupId>io.fabric8</groupId> + <artifactId>docker-maven-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.commonjava.maven.plugins</groupId> + <artifactId>directory-maven-plugin</artifactId> + </plugin> + </plugins> + </build> + </profile> + <profile> + <id>demo</id> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + </plugin> + </plugins> + </build> + </profile> + </profiles> + +</project> diff --git a/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/InventoryService.java b/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/InventoryService.java new file mode 100644 index 0000000..57279e8 --- /dev/null +++ b/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/InventoryService.java @@ -0,0 +1,54 @@ +package org.apache.servicecomb.saga.demo.pack.inventory; + +import java.util.Objects; +import org.apache.servicecomb.saga.omega.transaction.annotations.Participate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class InventoryService { + + private ProductDao productDao; + + /** + * Find the product with specific product Id. + * + * @param productId Product ID + * @param requiredCount Required product count + * @return return the reserved count, 0 if nothing is available. + */ + @Participate(confirmMethod = "confirm", cancelMethod = "cancel") + public Integer reserve(Long productId, int requiredCount) { + Product product = productDao.findOne(productId); + if (Objects.isNull(product)) { + throw new IllegalArgumentException("Product not exists at all"); + } + + // if it is sufficient + if (product.getAvailable() > requiredCount) { + product.setReserved(product.getReserved() + requiredCount); // reserve some product in stock + productDao.save(product); + return requiredCount; + } else { + return product.getAvailable() - requiredCount; + } + } + + public void confirm(Long productId, int requiredCount) { + Product product = productDao.findOne(productId); + product.setInStock(product.getInStock() - requiredCount); // actually reduce the in stock count + product.setReserved(product.getReserved() - requiredCount); // and remove the reserved count + productDao.save(product); + } + + public void cancel(Long productId, int requiredCount) { + Product product = productDao.findOne(productId); + product.setReserved(product.getReserved() - requiredCount); // remove the reserved count + productDao.save(product); + } + + @Autowired + public void setProductDao(ProductDao productDao) { + this.productDao = productDao; + } +} diff --git a/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/Product.java b/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/Product.java new file mode 100644 index 0000000..2fbc707 --- /dev/null +++ b/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/Product.java @@ -0,0 +1,85 @@ +package org.apache.servicecomb.saga.demo.pack.inventory; + +import java.io.Serializable; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import org.hibernate.annotations.Formula; + +@Entity +@Table(name = "t_product") +public class Product implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String name; + + /** + * Total count in stock + */ + private Integer inStock; + + /** + * reserved count + */ + private Integer reserved; + + Product() { + } + + Product(String name, Integer inStock, Integer reserved) { + this.name = name; + this.inStock = inStock; + this.reserved = reserved; + } + + /** + * Available in stock + */ + @Formula("in_Stock - reserved") + private Integer available; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getInStock() { + return inStock; + } + + public void setInStock(Integer inStock) { + this.inStock = inStock; + } + + public Integer getReserved() { + return reserved; + } + + public void setReserved(Integer reserved) { + this.reserved = reserved; + } + + public Integer getAvailable() { + return available; + } + + public void setAvailable(Integer available) { + this.available = available; + } +} diff --git a/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductController.java b/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductController.java new file mode 100644 index 0000000..def42a8 --- /dev/null +++ b/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductController.java @@ -0,0 +1,75 @@ +package org.apache.servicecomb.saga.demo.pack.inventory; + +import com.google.common.collect.ImmutableList; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@Controller +@RequestMapping("/product") +public class ProductController { + + private InventoryService inventoryService; + + @PostMapping("/product") + public Response updateInventory(@RequestParam("productId") Long productId, + @RequestParam("requiredCount") Integer requiredCount) { + return new Response(0, "OK", + ImmutableList.of(inventoryService.reserve(productId, requiredCount))); + } + + @ExceptionHandler + public Response exceptionHandler(Exception e) { + return new Response(-1, e.getMessage(), + ImmutableList.of(e.getStackTrace())); + } + + @Autowired + public void setInventoryService( + InventoryService inventoryService) { + this.inventoryService = inventoryService; + } +} + +class Response { + + private int code; + + private String message; + + private List<Object> objects; + + Response(int code, String message, List<Object> objects) { + this.code = code; + this.message = message; + this.objects = objects; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public List<Object> getObjects() { + return objects; + } + + public void setObjects(List<Object> objects) { + this.objects = objects; + } +} diff --git a/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductDao.java b/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductDao.java new file mode 100644 index 0000000..0b96353 --- /dev/null +++ b/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/ProductDao.java @@ -0,0 +1,7 @@ +package org.apache.servicecomb.saga.demo.pack.inventory; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ProductDao extends JpaRepository<Product, Long> { + +} diff --git a/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/TccInventoryApplication.java b/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/TccInventoryApplication.java new file mode 100644 index 0000000..909e8c0 --- /dev/null +++ b/saga-demo/tcc-spring-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/pack/inventory/TccInventoryApplication.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.saga.demo.pack.inventory; + +import org.apache.servicecomb.saga.omega.spring.EnableOmega; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; + +@SpringBootApplication +@EnableOmega +public class TccInventoryApplication { + + public static void main(String[] args) { + SpringApplication.run(TccInventoryApplication.class, args); + } + + @Bean + CommandLineRunner kickStart(ProductDao productDao) { + return args -> { + productDao.save(new Product("Bottled water", 100, 20)); + }; + } +} diff --git a/saga-demo/tcc-spring-demo/inventory/src/main/resources/application.yaml b/saga-demo/tcc-spring-demo/inventory/src/main/resources/application.yaml new file mode 100644 index 0000000..c8e3e32 --- /dev/null +++ b/saga-demo/tcc-spring-demo/inventory/src/main/resources/application.yaml @@ -0,0 +1,37 @@ +## --------------------------------------------------------------------------- +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); you may not use this file except in compliance with +## the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## --------------------------------------------------------------------------- +spring: + application: + name: inventory + datasource: + url: jdbc:h2:mem:inventory-test + h2: + console: + enabled: true + jpa: + show-sql: true + generate-ddl: true + hibernate: + ddl-auto: create-drop + naming: + physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy + implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy +alpha: + cluster: + address: alpha-server.servicecomb.io:8080 +server: + port: 10020 \ No newline at end of file diff --git a/saga-demo/tcc-spring-demo/inventory/src/main/resources/log4j2.xml b/saga-demo/tcc-spring-demo/inventory/src/main/resources/log4j2.xml new file mode 100644 index 0000000..cae04cb --- /dev/null +++ b/saga-demo/tcc-spring-demo/inventory/src/main/resources/log4j2.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<Configuration status="WARN"> + <Appenders> + <Console name="Console" target="SYSTEM_OUT"> + <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> + </Console> + </Appenders> + <Loggers> + <AsyncRoot level="info"> + <AppenderRef ref="Console"/> + </AsyncRoot> + </Loggers> +</Configuration> diff --git a/saga-demo/tcc-spring-demo/inventory/src/test/java/org/apache/servicecomb/saga/demo/pack/inventory/InventoryServiceTest.java b/saga-demo/tcc-spring-demo/inventory/src/test/java/org/apache/servicecomb/saga/demo/pack/inventory/InventoryServiceTest.java new file mode 100644 index 0000000..b8d51c6 --- /dev/null +++ b/saga-demo/tcc-spring-demo/inventory/src/test/java/org/apache/servicecomb/saga/demo/pack/inventory/InventoryServiceTest.java @@ -0,0 +1,28 @@ +package org.apache.servicecomb.saga.demo.pack.inventory; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@SpringBootTest +@RunWith(SpringJUnit4ClassRunner.class) +public class InventoryServiceTest { + + private InventoryService inventoryService; + + @Test + public void reserve() { + Integer count = inventoryService.reserve(1L, 10); + assertThat(count).isNotNull().isEqualTo(10); + } + + @Autowired + public void setInventoryService(InventoryService inventoryService) { + this.inventoryService = inventoryService; + } +} \ No newline at end of file diff --git a/saga-demo/tcc-spring-demo/inventory/src/test/resources/application.yaml b/saga-demo/tcc-spring-demo/inventory/src/test/resources/application.yaml new file mode 100644 index 0000000..c8e3e32 --- /dev/null +++ b/saga-demo/tcc-spring-demo/inventory/src/test/resources/application.yaml @@ -0,0 +1,37 @@ +## --------------------------------------------------------------------------- +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); you may not use this file except in compliance with +## the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## --------------------------------------------------------------------------- +spring: + application: + name: inventory + datasource: + url: jdbc:h2:mem:inventory-test + h2: + console: + enabled: true + jpa: + show-sql: true + generate-ddl: true + hibernate: + ddl-auto: create-drop + naming: + physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy + implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy +alpha: + cluster: + address: alpha-server.servicecomb.io:8080 +server: + port: 10020 \ No newline at end of file diff --git a/saga-demo/tcc-spring-demo/ordering/pom.xml b/saga-demo/tcc-spring-demo/ordering/pom.xml new file mode 100644 index 0000000..6cbbba1 --- /dev/null +++ b/saga-demo/tcc-spring-demo/ordering/pom.xml @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>saga-spring-demo</artifactId> + <groupId>org.apache.servicecomb.saga.demo</groupId> + <version>0.3.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>Tcc-Ordering</artifactId> + <name>Saga::Demo::Tcc-Spring-Demo::Tcc-Ordering</name> + + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + </dependency> + <dependency> + <groupId>org.apache.servicecomb.saga</groupId> + <artifactId>omega-spring-starter</artifactId> + </dependency> + <dependency> + <groupId>org.apache.servicecomb.saga</groupId> + <artifactId>omega-transport-resttemplate</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-data-jpa</artifactId> + </dependency> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <!-- mixin plugin configurations declared in another pom, + just like importing dependencies managed in another pom --> + <plugin> + <groupId>com.github.odavid.maven.plugins</groupId> + <artifactId>mixin-maven-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + </plugin> + </plugins> + </build> + + <profiles> + <profile> + <id>docker</id> + <activation> + <file> + <exists>/var/run/docker.sock</exists> + </file> + </activation> + <build> + <plugins> + <plugin> + <groupId>io.fabric8</groupId> + <artifactId>docker-maven-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.commonjava.maven.plugins</groupId> + <artifactId>directory-maven-plugin</artifactId> + </plugin> + </plugins> + </build> + </profile> + <profile> + <id>demo</id> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + </plugin> + </plugins> + </build> + </profile> + </profiles> + +</project> diff --git a/saga-demo/tcc-spring-demo/ordering/src/main/java/org/apache/servicecomb/saga/demo/pack/ordering/OrderingController.java b/saga-demo/tcc-spring-demo/ordering/src/main/java/org/apache/servicecomb/saga/demo/pack/ordering/OrderingController.java new file mode 100644 index 0000000..39aacc1 --- /dev/null +++ b/saga-demo/tcc-spring-demo/ordering/src/main/java/org/apache/servicecomb/saga/demo/pack/ordering/OrderingController.java @@ -0,0 +1,26 @@ +package org.apache.servicecomb.saga.demo.pack.ordering; + + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@Controller +@RequestMapping("/ordering") +public class OrderingController { + + @PostMapping("/{productId}") + public String ordering( + @RequestParam("requiredCount") Integer requiredCount) { + // place an order + + // try to reserve some product + + // create a purchase order and do the payment + + // create delivery order + + return ""; + } +} diff --git a/saga-demo/tcc-spring-demo/ordering/src/main/java/org/apache/servicecomb/saga/demo/pack/ordering/TccOrderingApplication.java b/saga-demo/tcc-spring-demo/ordering/src/main/java/org/apache/servicecomb/saga/demo/pack/ordering/TccOrderingApplication.java new file mode 100644 index 0000000..a4000fe --- /dev/null +++ b/saga-demo/tcc-spring-demo/ordering/src/main/java/org/apache/servicecomb/saga/demo/pack/ordering/TccOrderingApplication.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.saga.demo.pack.ordering; + +import org.apache.servicecomb.saga.omega.spring.EnableOmega; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +@EnableOmega +public class TccOrderingApplication { + public static void main(String[] args) { + SpringApplication.run(TccOrderingApplication.class, args); + } +} diff --git a/saga-demo/tcc-spring-demo/ordering/src/main/resources/application.yaml b/saga-demo/tcc-spring-demo/ordering/src/main/resources/application.yaml new file mode 100644 index 0000000..d2c82e0 --- /dev/null +++ b/saga-demo/tcc-spring-demo/ordering/src/main/resources/application.yaml @@ -0,0 +1,29 @@ +## --------------------------------------------------------------------------- +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); you may not use this file except in compliance with +## the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## --------------------------------------------------------------------------- +spring: + application: + name: ordering + datasource: + url: jdbc:h2:mem:ordering-test + h2: + console: + enabled: true +alpha: + cluster: + address: alpha-server.servicecomb.io:8080 +server: + port: 10010 \ No newline at end of file diff --git a/saga-demo/tcc-spring-demo/ordering/src/main/resources/log4j2.xml b/saga-demo/tcc-spring-demo/ordering/src/main/resources/log4j2.xml new file mode 100644 index 0000000..cae04cb --- /dev/null +++ b/saga-demo/tcc-spring-demo/ordering/src/main/resources/log4j2.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<Configuration status="WARN"> + <Appenders> + <Console name="Console" target="SYSTEM_OUT"> + <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> + </Console> + </Appenders> + <Loggers> + <AsyncRoot level="info"> + <AppenderRef ref="Console"/> + </AsyncRoot> + </Loggers> +</Configuration> diff --git a/saga-demo/tcc-spring-demo/ordering/src/main/resources/static/index.html b/saga-demo/tcc-spring-demo/ordering/src/main/resources/static/index.html new file mode 100644 index 0000000..894667f --- /dev/null +++ b/saga-demo/tcc-spring-demo/ordering/src/main/resources/static/index.html @@ -0,0 +1,91 @@ +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>Saga-booking-demo</title> + + <script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script> + + <script type="text/javascript"> + function testCase1() { + $.post("http://127.0.0.1:8083/booking/test/2/2", function(data) { + var msg = data; + $("#booking_result_1").html(msg); + }); + } + + function testCase2() { + $.post("http://127.0.0.1:8083/booking/test/3/2", function(data) { + var msg = data; + $("#booking_result_2").html(msg); + }) + .fail(function(data) { + alert("The transaction is failed"); + $("#booking_result_2").html("<li>" + JSON.stringify(data) + "</li>"); + }); + } + + function room_booking_result() { + $.get("http://127.0.0.1:8081/bookings", function(data) { + var msg = "<li>" + JSON.stringify(data) + "</li>"; + $("#room_list").html(msg); + }); + } + + function car_booking_result() { + $.get("http://127.0.0.1:8082/bookings", function(data) { + var msg = "<li>" + JSON.stringify(data) + "</li>"; + $("#car_list").html(msg); + }); + } + </script> +</head> +<body> +<p>Test cases of Sage booking demo:</p> +<p>Case 1. <a href="javascript:void(0);" onclick="testCase1();">[Booking 2 rooms and 2 cars, will done successfully]</a> </p> +<p> + Booking result: <span id="booking_result_1">###</span><br> +</p> +<br> +<p>Case 2. <a href="javascript:void(0);" onclick="testCase2();">[Booking 3 rooms and 2 cars, hotel order service will failed.]</a> </p> +<p> + Booking result: <span id="booking_result_2">###</span><br> +</p> +<br> +<p><a href="javascript:void(0);" onclick="room_booking_result();">[Query the room booking result]</a> </p> +<p> + Room booking list:<br> +<ul> + <li id="room_list"> + #Name, Amount, Confirm status, Cancel Status + </li> +</ul> +</p> +<br> +<p><a href="javascript:void(0);" onclick="car_booking_result();">[Query the car booking result]</a> </p> +<p> + Car booking list:<br> +<ul> + <li id="car_list"> + #Name, Amount, Confirm status, Cancel Status + </li> +</ul> +</p> +</body> +</html> diff --git a/saga-demo/tcc-spring-demo/payment/pom.xml b/saga-demo/tcc-spring-demo/payment/pom.xml new file mode 100644 index 0000000..e950acc --- /dev/null +++ b/saga-demo/tcc-spring-demo/payment/pom.xml @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>saga-spring-demo</artifactId> + <groupId>org.apache.servicecomb.saga.demo</groupId> + <version>0.3.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>Tcc-Payment</artifactId> + <name>Saga::Demo::Tcc-Spring-Demo::Tcc-Payment</name> + + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + </dependency> + <dependency> + <groupId>org.apache.servicecomb.saga</groupId> + <artifactId>omega-spring-starter</artifactId> + </dependency> + <dependency> + <groupId>org.apache.servicecomb.saga</groupId> + <artifactId>omega-transport-resttemplate</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-data-jpa</artifactId> + </dependency> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <!-- mixin plugin configurations declared in another pom, + just like importing dependencies managed in another pom --> + <plugin> + <groupId>com.github.odavid.maven.plugins</groupId> + <artifactId>mixin-maven-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + </plugin> + </plugins> + </build> + + <profiles> + <profile> + <id>docker</id> + <activation> + <file> + <exists>/var/run/docker.sock</exists> + </file> + </activation> + <build> + <plugins> + <plugin> + <groupId>io.fabric8</groupId> + <artifactId>docker-maven-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.commonjava.maven.plugins</groupId> + <artifactId>directory-maven-plugin</artifactId> + </plugin> + </plugins> + </build> + </profile> + <profile> + <id>demo</id> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + </plugin> + </plugins> + </build> + </profile> + </profiles> + +</project> diff --git a/saga-demo/tcc-spring-demo/payment/src/main/java/org/apache/servicecomb/saga/demo/pack/payment/TccPaymentApplication.java b/saga-demo/tcc-spring-demo/payment/src/main/java/org/apache/servicecomb/saga/demo/pack/payment/TccPaymentApplication.java new file mode 100644 index 0000000..9c5d795 --- /dev/null +++ b/saga-demo/tcc-spring-demo/payment/src/main/java/org/apache/servicecomb/saga/demo/pack/payment/TccPaymentApplication.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.saga.demo.pack.payment; + +import org.apache.servicecomb.saga.omega.spring.EnableOmega; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +@EnableOmega +public class TccPaymentApplication { + public static void main(String[] args) { + SpringApplication.run(TccPaymentApplication.class, args); + } +} diff --git a/saga-demo/tcc-spring-demo/payment/src/main/resources/application.yaml b/saga-demo/tcc-spring-demo/payment/src/main/resources/application.yaml new file mode 100644 index 0000000..1838533 --- /dev/null +++ b/saga-demo/tcc-spring-demo/payment/src/main/resources/application.yaml @@ -0,0 +1,29 @@ +## --------------------------------------------------------------------------- +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You under the Apache License, Version 2.0 +## (the "License"); you may not use this file except in compliance with +## the License. You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## --------------------------------------------------------------------------- +spring: + application: + name: hotel + datasource: + url: jdbc:h2:mem:payment-test + h2: + console: + enabled: true +alpha: + cluster: + address: alpha-server.servicecomb.io:8080 +server: + port: 10030 \ No newline at end of file diff --git a/saga-demo/tcc-spring-demo/payment/src/main/resources/log4j2.xml b/saga-demo/tcc-spring-demo/payment/src/main/resources/log4j2.xml new file mode 100644 index 0000000..cae04cb --- /dev/null +++ b/saga-demo/tcc-spring-demo/payment/src/main/resources/log4j2.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<Configuration status="WARN"> + <Appenders> + <Console name="Console" target="SYSTEM_OUT"> + <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> + </Console> + </Appenders> + <Loggers> + <AsyncRoot level="info"> + <AppenderRef ref="Console"/> + </AsyncRoot> + </Loggers> +</Configuration> diff --git a/saga-demo/tcc-spring-demo/pom.xml b/saga-demo/tcc-spring-demo/pom.xml new file mode 100644 index 0000000..a020802 --- /dev/null +++ b/saga-demo/tcc-spring-demo/pom.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>saga-demo</artifactId> + <groupId>org.apache.servicecomb.saga.demo</groupId> + <version>0.3.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>tcc-spring-demo</artifactId> + <name>Saga::Demo::Tcc-Spring-Demo</name> + <packaging>pom</packaging> + + <modules> + <module>ordering</module> + <module>payment</module> + <module>inventory</module> + </modules> + + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-actuator</artifactId> + </dependency> + <dependency> + <groupId>io.netty</groupId> + <artifactId>netty-tcnative-boringssl-static</artifactId> + </dependency> + </dependencies> +</project> diff --git a/saga-demo/tcc-spring-demo/saga-demo.sh b/saga-demo/tcc-spring-demo/saga-demo.sh new file mode 100644 index 0000000..2b3cf47 --- /dev/null +++ b/saga-demo/tcc-spring-demo/saga-demo.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +service=saga-demo + +show_usage() { + echo "Usage: $0 {up|up-alpha|up-demo|up-mysql|down}" >&2 +} + +fetch_version() { + version="$(printf 'VER\t${project.version}' | mvn help:evaluate | grep '^VER' | cut -f2)" +} + +if [[ -z $1 ]]; then + show_usage + exit 2 +fi + +case $1 in + up) + fetch_version + echo "Starting ${service}:${version}" + TAG=$version docker-compose up + exit $? + ;; + + up-alpha) + fetch_version + echo "Starting ${service}:${version}" + TAG=$version docker-compose -f docker-compose-alpha.yaml up + exit $? + ;; + + up-demo) + fetch_version + echo "Starting ${service}:${version}" + TAG=$version docker-compose -f docker-compose-demo.yaml up + exit $? + ;; + + up-mysql) + fetch_version + echo "Starting ${service}:${version}" + TAG=$version docker-compose -f docker-compose.yaml -f docker-compose.mysql.yaml up + exit $? + ;; + + down) + fetch_version + echo "Stopping ${service}:${version}" + TAG=$version docker-compose down + exit $? + ;; + + *) + show_usage + exit 2 + ;; +esac +
