SCB-151 Update to add the pack-demo
diff --git a/saga-demo/pack-demo/README.md b/saga-demo/pack-demo/README.md
new file mode 100644
index 0000000..1e8d700
--- /dev/null
+++ b/saga-demo/pack-demo/README.md
@@ -0,0 +1,48 @@
+# Pack Transaction Demo
+This demo simulates a booking application including three services:
+* pack-booking
+* pack-car
+* pack-hotel
+
+## Running Demo
+1. run the following command to create docker images in saga project root folder.
+```
+mvn package -DskipTests -Pdocker -Pdemo
+```
+
+2. start application up in saga/saga-demo/pack-demo with the following command
+```
+docker-compose up
+```
+
+## User Requests
+1. Booking 2 rooms and 2 cars, this booking will be OK.
+```
+curl -X POST http://{docker.host.ip}:8083/booking/test/2/2
+```
+Check the hotel booking status with
+```
+curl http://{docker.host.ip}:8081/bookings
+```
+Check the car booking status with
+```
+curl http://{docker.host.ip}:8082/bookings
+
+```
+
+2. Booking 3 rooms and 2 cars, this booking will case the hotel order failed and trigger the compansate operation with car booking.
+```
+curl -X POST http://{docker.host.ip}:8083/booking/test/3/2
+```
+Check the hotel booking status with
+```
+curl http://{docker.host.ip}:8081/bookings
+```
+Check the car booking status with
+```
+curl http://{docker.host.ip}:8082/bookings
+```
+The second car booking will be marked with **cancel:true**
+
+
+**Note** transactions and compensations implemented by services must be idempotent.
diff --git a/saga-demo/pack-demo/booking/pom.xml b/saga-demo/pack-demo/booking/pom.xml
new file mode 100644
index 0000000..47a8f9e
--- /dev/null
+++ b/saga-demo/pack-demo/booking/pom.xml
@@ -0,0 +1,82 @@
+<?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>pack-demo</artifactId>
+    <groupId>org.apache.servicecomb.saga.demo</groupId>
+    <version>0.0.3-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>pack-booking</artifactId>
+  <name>Saga::Demo::Pack::Booking</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>
+  </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>
+      <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>
+  </profiles>
+
+</project>
diff --git a/saga-demo/pack-demo/booking/src/main/java/org/apache/servicecomb/saga/demo/pack/booking/Application.java b/saga-demo/pack-demo/booking/src/main/java/org/apache/servicecomb/saga/demo/pack/booking/Application.java
new file mode 100644
index 0000000..2dda806
--- /dev/null
+++ b/saga-demo/pack-demo/booking/src/main/java/org/apache/servicecomb/saga/demo/pack/booking/Application.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.booking;
+
+import org.apache.servicecomb.saga.omega.spring.EnableOmega;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@EnableOmega
+public class Application {
+  public static void main(String[] args) {
+    SpringApplication.run(Application.class, args);
+  }
+}
diff --git a/saga-demo/pack-demo/booking/src/main/java/org/apache/servicecomb/saga/demo/pack/booking/BookingController.java b/saga-demo/pack-demo/booking/src/main/java/org/apache/servicecomb/saga/demo/pack/booking/BookingController.java
new file mode 100644
index 0000000..a2d88a4
--- /dev/null
+++ b/saga-demo/pack-demo/booking/src/main/java/org/apache/servicecomb/saga/demo/pack/booking/BookingController.java
@@ -0,0 +1,45 @@
+/*
+ * 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.booking;
+
+import org.apache.servicecomb.saga.omega.context.annotations.SagaStart;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.RestTemplate;
+
+@RestController
+public class BookingController {
+  @Autowired
+  private RestTemplate template;
+
+  @SagaStart
+  @PostMapping("/booking/{name}/{rooms}/{cars}")
+  public String order(@PathVariable String name,  @PathVariable Integer rooms, @PathVariable Integer cars) {
+    template.postForEntity(
+        "http://pack-car.servicecomb.io:8080/order/{name}/{cars}",
+        null, String.class, name, cars);
+
+    template.postForEntity(
+        "http://pack-hotel.servicecomb.io:8080/order/{name}/{rooms}",
+        null, String.class, name, rooms);
+
+    return name + " booking " + rooms + " rooms and " + cars + " cars OK";
+  }
+}
diff --git a/saga-demo/pack-demo/booking/src/main/resources/application.yaml b/saga-demo/pack-demo/booking/src/main/resources/application.yaml
new file mode 100644
index 0000000..ef8f833
--- /dev/null
+++ b/saga-demo/pack-demo/booking/src/main/resources/application.yaml
@@ -0,0 +1,22 @@
+## ---------------------------------------------------------------------------
+## 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: pack-booking
+alpha:
+  cluster:
+    address: alpha-server.servicecomb.io:8080
diff --git a/saga-demo/pack-demo/car/pom.xml b/saga-demo/pack-demo/car/pom.xml
new file mode 100644
index 0000000..78ebd5f
--- /dev/null
+++ b/saga-demo/pack-demo/car/pom.xml
@@ -0,0 +1,82 @@
+<?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>pack-demo</artifactId>
+    <groupId>org.apache.servicecomb.saga.demo</groupId>
+    <version>0.0.3-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>pack-car</artifactId>
+  <name>Saga::Demo::Pack::Car</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>
+  </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>
+      <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>
+  </profiles>
+
+</project>
diff --git a/saga-demo/pack-demo/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/Application.java b/saga-demo/pack-demo/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/Application.java
new file mode 100644
index 0000000..a4fe3d9
--- /dev/null
+++ b/saga-demo/pack-demo/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/Application.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.car;
+
+import org.apache.servicecomb.saga.omega.spring.EnableOmega;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@EnableOmega
+public class Application {
+  public static void main(String[] args) {
+    SpringApplication.run(Application.class, args);
+  }
+}
diff --git a/saga-demo/pack-demo/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/CarBooking.java b/saga-demo/pack-demo/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/CarBooking.java
new file mode 100644
index 0000000..11b936d
--- /dev/null
+++ b/saga-demo/pack-demo/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/CarBooking.java
@@ -0,0 +1,66 @@
+/*
+ * 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.car;
+
+public class CarBooking {
+  private Integer id;
+  private String name;
+  private Integer cars;
+  private boolean confirm;
+  private boolean cancel;
+
+  public Integer getId() {
+    return id;
+  }
+
+  public void setId(Integer id) {
+    this.id = id;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  public Integer getCars() {
+    return cars;
+  }
+
+  public void setCars(Integer cars) {
+    this.cars = cars;
+  }
+
+  public boolean isConfirm() {
+    return confirm;
+  }
+
+  public void setConfirm(boolean confirm) {
+    this.confirm = confirm;
+  }
+
+  public boolean isCancel() {
+    return cancel;
+  }
+
+  public void setCancel(boolean cancel) {
+    this.cancel = cancel;
+  }
+}
diff --git a/saga-demo/pack-demo/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/CarBookingController.java b/saga-demo/pack-demo/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/CarBookingController.java
new file mode 100644
index 0000000..60849aa
--- /dev/null
+++ b/saga-demo/pack-demo/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/CarBookingController.java
@@ -0,0 +1,50 @@
+/*
+ * 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.car;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+@RestController
+public class CarBookingController {
+  @Autowired
+  private CarBookingService service;
+
+  private AtomicInteger id = new AtomicInteger(0);
+
+  @GetMapping("/bookings") List<CarBooking> getAll() {
+    return new ArrayList<>(service.getAllBookings());
+  }
+
+  @PostMapping("/order/{name}/{cars}")
+  CarBooking order(@PathVariable String name, @PathVariable Integer cars) {
+    CarBooking booking = new CarBooking();
+    booking.setId(id.incrementAndGet());
+    booking.setName(name);
+    booking.setCars(cars);
+    service.order(booking);
+    return booking;
+  }
+}
diff --git a/saga-demo/pack-demo/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/CarBookingService.java b/saga-demo/pack-demo/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/CarBookingService.java
new file mode 100644
index 0000000..8c3f8f4
--- /dev/null
+++ b/saga-demo/pack-demo/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/CarBookingService.java
@@ -0,0 +1,49 @@
+/*
+ * 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.car;
+
+import org.apache.servicecomb.saga.omega.transaction.annotations.Compensable;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Service
+public class CarBookingService {
+  private ConcurrentHashMap<Integer, CarBooking> bookings = new ConcurrentHashMap<>();
+
+  @Compensable(compensationMethod = "cancel")
+  public void order(CarBooking booking) {
+    booking.setConfirm(true);
+    booking.setCancel(false);
+    bookings.put(booking.getId(), booking);
+  }
+
+  public void cancel(CarBooking booking) {
+    Integer id = booking.getId();
+    if (bookings.containsKey(id)) {
+      CarBooking origin = bookings.get(id);
+      origin.setConfirm(false);
+      origin.setCancel(true);
+    }
+  }
+
+  public Collection<CarBooking> getAllBookings() {
+    return bookings.values();
+  }
+}
diff --git a/saga-demo/pack-demo/car/src/main/resources/application.yaml b/saga-demo/pack-demo/car/src/main/resources/application.yaml
new file mode 100644
index 0000000..2a1c2b7
--- /dev/null
+++ b/saga-demo/pack-demo/car/src/main/resources/application.yaml
@@ -0,0 +1,22 @@
+## ---------------------------------------------------------------------------
+## 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: pack-car
+alpha:
+  cluster:
+    address: alpha-server.servicecomb.io:8080
diff --git a/saga-demo/pack-demo/docker-compose.yaml b/saga-demo/pack-demo/docker-compose.yaml
new file mode 100644
index 0000000..b452d24
--- /dev/null
+++ b/saga-demo/pack-demo/docker-compose.yaml
@@ -0,0 +1,76 @@
+## ---------------------------------------------------------------------------
+## 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:
+  postgres:
+    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:0.0.3-SNAPSHOT"
+    hostname: alpha-server
+    links:
+      - "postgres:postgresql.servicecomb.io"
+    environment:
+      - JAVA_OPTS=-Dspring.profiles.active=prd
+    depends_on:
+      postgres:
+        condition: service_healthy
+
+  pack-hotel:
+    image: "pack-hotel:0.0.3-SNAPSHOT"
+    hostname: pack-hotel
+    links:
+      - "alpha:alpha-server.servicecomb.io"
+    ports:
+      - "8081:8080"
+    depends_on:
+      - alpha
+
+  pack-car:
+    image: "pack-car:0.0.3-SNAPSHOT"
+    hostname: pack-car
+    links:
+      - "alpha:alpha-server.servicecomb.io"
+    ports:
+      - "8082:8080"
+    depends_on:
+      - alpha
+
+  pack-booking:
+    image: "pack-booking:0.0.3-SNAPSHOT"
+    hostname: pack-booking
+    links:
+      - "alpha:alpha-server.servicecomb.io"
+      - "pack-hotel:pack-hotel.servicecomb.io"
+      - "pack-car:pack-car.servicecomb.io"
+    ports:
+      - "8083:8080"
+    depends_on:
+      - pack-hotel
+      - pack-car
diff --git a/saga-demo/pack-demo/hotel/pom.xml b/saga-demo/pack-demo/hotel/pom.xml
new file mode 100644
index 0000000..8b4dc09
--- /dev/null
+++ b/saga-demo/pack-demo/hotel/pom.xml
@@ -0,0 +1,82 @@
+<?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>pack-demo</artifactId>
+    <groupId>org.apache.servicecomb.saga.demo</groupId>
+    <version>0.0.3-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>pack-hotel</artifactId>
+  <name>Saga::Demo::Pack::Hotel</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>
+  </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>
+      <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>
+  </profiles>
+
+</project>
diff --git a/saga-demo/pack-demo/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/Application.java b/saga-demo/pack-demo/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/Application.java
new file mode 100644
index 0000000..26a55e3
--- /dev/null
+++ b/saga-demo/pack-demo/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/Application.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.hotel;
+
+import org.apache.servicecomb.saga.omega.spring.EnableOmega;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@EnableOmega
+public class Application {
+  public static void main(String[] args) {
+    SpringApplication.run(Application.class, args);
+  }
+}
diff --git a/saga-demo/pack-demo/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/HotelBooking.java b/saga-demo/pack-demo/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/HotelBooking.java
new file mode 100644
index 0000000..e7c748c
--- /dev/null
+++ b/saga-demo/pack-demo/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/HotelBooking.java
@@ -0,0 +1,66 @@
+/*
+ * 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.hotel;
+
+public class HotelBooking {
+  private Integer id;
+  private String name;
+  private Integer rooms;
+  private boolean confirm;
+  private boolean cancel;
+
+  public Integer getId() {
+    return id;
+  }
+
+  public void setId(Integer id) {
+    this.id = id;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  public Integer getRooms() {
+    return rooms;
+  }
+
+  public void setRooms(Integer rooms) {
+    this.rooms = rooms;
+  }
+
+  public boolean isConfirm() {
+    return confirm;
+  }
+
+  public void setConfirm(boolean confirm) {
+    this.confirm = confirm;
+  }
+
+  public boolean isCancel() {
+    return cancel;
+  }
+
+  public void setCancel(boolean cancel) {
+    this.cancel = cancel;
+  }
+}
diff --git a/saga-demo/pack-demo/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/HotelBookingController.java b/saga-demo/pack-demo/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/HotelBookingController.java
new file mode 100644
index 0000000..0474d71
--- /dev/null
+++ b/saga-demo/pack-demo/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/HotelBookingController.java
@@ -0,0 +1,51 @@
+/*
+ * 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.hotel;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+@RestController
+public class HotelBookingController {
+  @Autowired
+  private HotelBookingService service;
+
+  private AtomicInteger id = new AtomicInteger(0);
+
+  @GetMapping("/bookings")
+  List<HotelBooking> getAll() {
+    return new ArrayList<>(service.getAllBookings());
+  }
+
+  @PostMapping("/order/{name}/{rooms}")
+  HotelBooking order(@PathVariable String name, @PathVariable Integer rooms) {
+    HotelBooking booking = new HotelBooking();
+    booking.setId(id.incrementAndGet());
+    booking.setName(name);
+    booking.setRooms(rooms);
+    service.order(booking);
+    return booking;
+  }
+}
diff --git a/saga-demo/pack-demo/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/HotelBookingService.java b/saga-demo/pack-demo/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/HotelBookingService.java
new file mode 100644
index 0000000..d819843
--- /dev/null
+++ b/saga-demo/pack-demo/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/HotelBookingService.java
@@ -0,0 +1,52 @@
+/*
+ * 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.hotel;
+
+import org.apache.servicecomb.saga.omega.transaction.annotations.Compensable;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Service
+public class HotelBookingService {
+  private ConcurrentHashMap<Integer, HotelBooking> bookings = new ConcurrentHashMap<>();
+
+  @Compensable(compensationMethod = "cancel")
+  public void order(HotelBooking booking) {
+    if (booking.getRooms() > 2) {
+      throw new IllegalArgumentException("can not order the rooms large than two");
+    }
+    booking.setConfirm(true);
+    booking.setCancel(false);
+    bookings.put(booking.getId(), booking);
+  }
+
+  public void cancel(HotelBooking booking) {
+    Integer id = booking.getId();
+    if (bookings.containsKey(id)) {
+      HotelBooking origin = bookings.get(id);
+      origin.setConfirm(false);
+      origin.setCancel(true);
+    }
+  }
+
+  public Collection<HotelBooking> getAllBookings() {
+    return bookings.values();
+  }
+}
diff --git a/saga-demo/pack-demo/hotel/src/main/resources/application.yaml b/saga-demo/pack-demo/hotel/src/main/resources/application.yaml
new file mode 100644
index 0000000..cb03be0
--- /dev/null
+++ b/saga-demo/pack-demo/hotel/src/main/resources/application.yaml
@@ -0,0 +1,22 @@
+## ---------------------------------------------------------------------------
+## 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: pack-hotel
+alpha:
+  cluster:
+    address: alpha-server.servicecomb.io:8080
diff --git a/saga-demo/pack-demo/pom.xml b/saga-demo/pack-demo/pom.xml
new file mode 100644
index 0000000..3b3453e
--- /dev/null
+++ b/saga-demo/pack-demo/pom.xml
@@ -0,0 +1,37 @@
+<?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.0.3-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>pack-demo</artifactId>
+  <name>Saga::Demo::Pack</name>
+  <packaging>pom</packaging>
+
+  <modules>
+    <module>booking</module>
+    <module>car</module>
+    <module>hotel</module>
+  </modules>
+
+</project>
diff --git a/saga-demo/pom.xml b/saga-demo/pom.xml
index 4e6c28c..dfdef26 100644
--- a/saga-demo/pom.xml
+++ b/saga-demo/pom.xml
@@ -32,6 +32,7 @@
   <modules>
     <module>dependency-free-transaction-demo</module>
     <module>conditional-transaction-demo</module>
+    <module>pack-demo</module>
   </modules>
 
   <dependencyManagement>