servicecomb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From GitBox <...@apache.org>
Subject [GitHub] WillemJiang closed pull request #139: SCB-363 Remove legacy code
Date Sun, 04 Mar 2018 12:04:47 GMT
WillemJiang closed pull request #139: SCB-363 Remove legacy code
URL: https://github.com/apache/incubator-servicecomb-saga/pull/139
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/README.md b/README.md
index 61c9c8f8..41903393 100644
--- a/README.md
+++ b/README.md
@@ -17,10 +17,10 @@ Saga is composed of  **alpha** and **omega**.
 The following diagram shows the relationships among alpha, omega and services.
 ![Saga Pack Architecture](docs/static_files/pack.png)
 
-See [Saga Pack Design](docs/design.md) for details. If you are interested in our previous architecture, please move forward to [Old Saga's Documentation](docs/old_saga.md).
+See [Saga Pack Design](docs/design.md) for details. 
 
 ## Get Started
-See [Booking Demo](saga-demo/pack-demo/README.md) for details.
+See [Booking Demo](saga-demo/booking/README.md) for details.
 
 ## User Guide
 See [User Guide](docs/user_guide.md) for details.
diff --git a/README_ZH.md b/README_ZH.md
index ac5f8a3e..1b055926 100644
--- a/README_ZH.md
+++ b/README_ZH.md
@@ -17,10 +17,10 @@ Saga?? **alpha** ? **omega**??????
 ?????alpha, omega???????????
 ![Saga Pack ??](docs/static_files/pack.png)
 
-?????[Saga Pack ????](docs/design_zh.md). ????Saga??????????????[???Saga??](docs/old_saga.md)?????
+?????[Saga Pack ????](docs/design_zh.md). 
 
 ## ????
-?????[??????](saga-demo/pack-demo/README.md)?
+?????[??????](saga-demo/booking/README.md)?
 
 ## ????
 ?????[????](docs/user_guide_zh.md)?
diff --git a/docs/api/api.md b/docs/api/api.md
deleted file mode 100755
index e0a9e8fc..00000000
--- a/docs/api/api.md
+++ /dev/null
@@ -1,168 +0,0 @@
-# Saga API
-### Post transaction and compensation requests to Saga
-```
-POST /requests
-```
-
-####  Description
-
-1. Define requests in order and recovery policy by JSON format as below,put them to body.
-```
-{
-  "policy": "",
-  "requests": [
-    {
-      "id": "",
-      "type": "",
-      "serviceName": "",
-      "parents": [
-
-      ],
-      "transaction": {
-        "method": "",
-        "path": "",
-        "params": {
-
-        }
-      },
-      "compensation": {
-        "method": "",
-        "path": "",
-        "params": {
-
-        }
-      }
-    }
-  ]
-}
-```
-JSON parameters:
-- policy - support `BackwardRecovery` or `ForwardRecovery`.
-- requests - transactions array.
-  - id - request id. It should be unique among this collection of requests.
-  - type - support `rest` for now.
-  - serviceName - user-defined service name.
-  - parents - request ids. It means this request is only executed after all requests in the parents field are completed.
-  - transaction - user-defined transaction that executed by the Saga.
-    - method - user-defined, HTTP method.
-    - path - user-defined, HTTP path.
-    - params - support `form`,`json`,`body`,`query`.
-  - compensation - user-defined compensation that executed by the Saga.
-    - method - user-defined, HTTP method.
-    - path - user-defined, HTTP path.
-    - params - support `form`,`json`,`body`,`query`.
-
-2. Set content type to `text/plain`.
-
-3. Send them to Saga service.
-
-####  Example request
-```
-curl -XPOST -H "Content-Type: text/plain" -d @./request.json  http://<docker.host.ip:saga.port>/requests
-```
-
-####  Example response
-```
-success
-```
-
-####  Status codes
--   **200** ? no error
--   **400** ? bad parameter
--   **500** ? server error
-
-
-### Get all the Saga events
-```
-GET /events
-```
-
-####  Description
-Get all the Saga events.
-
-####  Example request
-```
-curl -XGET http://<docker.host.ip:saga.port>/events
-```
-
-####  Example response
-```
-{
-    "88658e73-eff5-4d31-887e-019201d6b560": [
-        {
-            "id": 1,
-            "sagaId": "88658e73-eff5-4d31-887e-019201d6b560",
-            "creationTime": "2017-09-15T01:15:40Z",
-            "type": "SagaStartedEvent",
-            "contentJson": "{\"policy\": \"BackwardRecovery\", \"requests\": [{\"id\": \"request-car\", \"type\": \"rest\", \"serviceName\": \"car-rental-service\", \"transaction\": {\"path\": \"/rentals\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/rentals\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}}, {\"id\": \"request-hotel\", \"type\": \"rest\", \"serviceName\": \"hotel-reservation-service\", \"transaction\": {\"path\": \"/reservations\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/reservations\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}}, {\"id\": \"request-flight\", \"type\": \"rest\", \"serviceName\": \"flight-booking-service\", \"transaction\": {\"path\": \"/bookings\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/bookings\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}}, {\"id\": \"request-payment\", \"type\": \"rest\", \"parents\": [\"request-car\", \"request-flight\", \"request-hotel\"], \"serviceName\": \"payment-service\", \"transaction\": {\"path\": \"/payments\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/payments\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}}]}"
-        },
-        {
-            "id": 2,
-            "sagaId": "88658e73-eff5-4d31-887e-019201d6b560",
-            "creationTime": "2017-09-15T01:15:40Z",
-            "type": "TransactionStartedEvent",
-            "contentJson": "{\"id\": \"request-flight\", \"type\": \"rest\", \"parents\": [], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"flight-booking-service\", \"transaction\": {\"path\": \"/bookings\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/bookings\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}"
-        },
-        {
-            "id": 3,
-            "sagaId": "88658e73-eff5-4d31-887e-019201d6b560",
-            "creationTime": "2017-09-15T01:15:40Z",
-            "type": "TransactionStartedEvent",
-            "contentJson": "{\"id\": \"request-car\", \"type\": \"rest\", \"parents\": [], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"car-rental-service\", \"transaction\": {\"path\": \"/rentals\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/rentals\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}"
-        },
-        {
-            "id": 4,
-            "sagaId": "88658e73-eff5-4d31-887e-019201d6b560",
-            "creationTime": "2017-09-15T01:15:40Z",
-            "type": "TransactionStartedEvent",
-            "contentJson": "{\"id\": \"request-hotel\", \"type\": \"rest\", \"parents\": [], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"hotel-reservation-service\", \"transaction\": {\"path\": \"/reservations\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/reservations\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}"
-        },
-        {
-            "id": 5,
-            "sagaId": "88658e73-eff5-4d31-887e-019201d6b560",
-            "creationTime": "2017-09-15T01:15:40Z",
-            "type": "TransactionEndedEvent",
-            "contentJson": "{\"request\": {\"id\": \"request-flight\", \"type\": \"rest\", \"parents\": [], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"flight-booking-service\", \"transaction\": {\"path\": \"/bookings\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/bookings\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}, \"response\": {\"body\": \"{\\n  \\\"statusCode\\\": 200,\\n  \\\"content\\\": \\\"Flight booked with id 5b3c462a-b5d4-45b8-b5e4-8c9aa7d1c069 for customer mike\\\"\\n}\"}}"
-        },
-        {
-            "id": 6,
-            "sagaId": "88658e73-eff5-4d31-887e-019201d6b560",
-            "creationTime": "2017-09-15T01:15:40Z",
-            "type": "TransactionEndedEvent",
-            "contentJson": "{\"request\": {\"id\": \"request-hotel\", \"type\": \"rest\", \"parents\": [], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"hotel-reservation-service\", \"transaction\": {\"path\": \"/reservations\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/reservations\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}, \"response\": {\"body\": \"{\\n  \\\"statusCode\\\": 200,\\n  \\\"content\\\": \\\"Hotel reserved with id eb2366e1-411d-4352-84fb-6b5ab446ec81 for customer mike\\\"\\n}\"}}"
-        },
-        {
-            "id": 7,
-            "sagaId": "88658e73-eff5-4d31-887e-019201d6b560",
-            "creationTime": "2017-09-15T01:15:41Z",
-            "type": "TransactionEndedEvent",
-            "contentJson": "{\"request\": {\"id\": \"request-car\", \"type\": \"rest\", \"parents\": [], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"car-rental-service\", \"transaction\": {\"path\": \"/rentals\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/rentals\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}, \"response\": {\"body\": \"{\\n  \\\"statusCode\\\": 200,\\n  \\\"content\\\": \\\"Car rented with id 3c22da64-d4ac-4870-b9bb-54b603721925 for customer mike\\\"\\n}\"}}"
-        },
-        {
-            "id": 8,
-            "sagaId": "88658e73-eff5-4d31-887e-019201d6b560",
-            "creationTime": "2017-09-15T01:15:41Z",
-            "type": "TransactionStartedEvent",
-            "contentJson": "{\"id\": \"request-payment\", \"type\": \"rest\", \"parents\": [\"request-car\", \"request-flight\", \"request-hotel\"], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"payment-service\", \"transaction\": {\"path\": \"/payments\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/payments\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}"
-        },
-        {
-            "id": 9,
-            "sagaId": "88658e73-eff5-4d31-887e-019201d6b560",
-            "creationTime": "2017-09-15T01:15:41Z",
-            "type": "TransactionEndedEvent",
-            "contentJson": "{\"request\": {\"id\": \"request-payment\", \"type\": \"rest\", \"parents\": [\"request-car\", \"request-flight\", \"request-hotel\"], \"fallback\": {\"type\": \"NOP\"}, \"serviceName\": \"payment-service\", \"transaction\": {\"path\": \"/payments\", \"method\": \"post\", \"params\": {\"form\": {\"customerId\": \"mike\"}}}, \"compensation\": {\"path\": \"/payments\", \"method\": \"put\", \"params\": {\"form\": {\"customerId\": \"mike\"}}, \"retries\": 3}}, \"response\": {\"body\": \"{\\n  \\\"statusCode\\\": 200,\\n  \\\"content\\\": \\\"Payment made for customer mike and remaining balance is 200\\\"\\n}\"}}"
-        },
-        {
-            "id": 10,
-            "sagaId": "88658e73-eff5-4d31-887e-019201d6b560",
-            "creationTime": "2017-09-15T01:15:41Z",
-            "type": "SagaEndedEvent",
-            "contentJson": "{}"
-        }
-    ]
-}
-```
-
-####  Status codes
--   **200** ? no error
-
diff --git a/docs/old_saga.md b/docs/old_saga.md
deleted file mode 100755
index 2b79d221..00000000
--- a/docs/old_saga.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# Previous Saga's Documentation
-## Major Architecture of Saga
-* saga-core(transaction and compensation handling logic)
-* saga-format(data serialization and deserialization)
-* saga-transports(communication protocol implementation such as rest or rpc in the future)
-* saga-discovery(service discovery)
-* saga-spring(restful service framework)
-
-![Saga](static_files/saga.png) 
-
-## Prerequisites
-You will need:
-1. [Oracle JDK 1.8+][jdk]
-2. [Maven 3.x][maven]
-3. [Docker][docker]
-4. [PostgreSQL][postgres]
-5. [Service Center(optional)][service_center]
-6. [Docker compose(optional)][docker_compose]
-7. [Docker machine(optional)][docker_machine]
-
-[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
-[postgres]: https://www.postgresql.org/download/
-[service_center]: https://github.com/apache/incubator-servicecomb-service-center
-[docker_compose]: https://docs.docker.com/compose/install/
-[docker_machine]: https://docs.docker.com/machine/install-machine/
-
-## Building
-Download the source code.
-```
-git clone https://github.com/apache/incubator-servicecomb-saga.git
-```
-
-Enter the Saga root directory,build Saga project by maven command and generate a docker image named saga-spring in local.
-```
-mvn package -DskipTests -Pdocker
-```
-
-## Run Services
-A `docker-compose.yaml` file is provided to start Saga services and its dependencies(Service center and Mysql) as docker containers.
-User also can configure specified Service center or Mysql in `docker-compose.yaml`.
-
-Enter the Saga root directory, run all service images using command,
-```
-docker-compose up
-```
-
-## Reference API
-See [Saga API](docs/api/api.md) for details.
-
-## Example
-See [Saga demo](https://github.com/apache/incubator-servicecomb-saga/tree/master/saga-demo) for details.
diff --git a/integration-tests/coverage-aggregate/pom.xml b/integration-tests/coverage-aggregate/pom.xml
index a156600c..cbb67ad9 100644
--- a/integration-tests/coverage-aggregate/pom.xml
+++ b/integration-tests/coverage-aggregate/pom.xml
@@ -29,26 +29,6 @@
 
 
   <dependencies>
-    <dependency>
-      <groupId>org.apache.servicecomb.saga</groupId>
-      <artifactId>saga-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.servicecomb.saga</groupId>
-      <artifactId>saga-format</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.servicecomb.saga</groupId>
-      <artifactId>saga-spring</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.servicecomb.saga.transports</groupId>
-      <artifactId>transport-httpclient</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.servicecomb.saga.discovery</groupId>
-      <artifactId>saga-discovery-servicecenter</artifactId>
-    </dependency>
     <dependency>
       <groupId>org.apache.servicecomb.saga</groupId>
       <artifactId>omega-context</artifactId>
diff --git a/pom.xml b/pom.xml
index 85e94050..9207e14e 100755
--- a/pom.xml
+++ b/pom.xml
@@ -31,19 +31,12 @@
   <version>0.0.3-SNAPSHOT</version>
 
   <modules>
-    <module>saga-core</module>
-    <module>transports</module>
-    <module>saga-spring</module>
     <module>docker-build-config</module>
-    <module>saga-format</module>
-    <module>saga-discovery</module>
-    <module>saga-web</module>
     <module>omega</module>
     <module>alpha</module>
     <module>pack-contracts</module>
     <module>pack-common</module>
     <module>integration-tests</module>
-    <module>saga-persistence</module>
   </modules>
 
   <properties>
@@ -121,41 +114,6 @@
 
   <dependencyManagement>
     <dependencies>
-      <dependency>
-        <groupId>org.apache.servicecomb.saga</groupId>
-        <artifactId>saga-core</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.servicecomb.saga</groupId>
-        <artifactId>saga-format</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.servicecomb.saga</groupId>
-        <artifactId>saga-spring</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.servicecomb.saga.transports</groupId>
-        <artifactId>transport-httpclient</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.servicecomb.saga.transports</groupId>
-        <artifactId>transport-httpclient-spring</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.servicecomb.saga.transports</groupId>
-        <artifactId>transport-resttemplate</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.servicecomb.saga.discovery</groupId>
-        <artifactId>saga-discovery-servicecenter</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
       <dependency>
         <groupId>org.apache.servicecomb.saga</groupId>
         <artifactId>omega-context</artifactId>
@@ -212,10 +170,10 @@
         <version>0.0.3-SNAPSHOT</version>
       </dependency>
       <dependency>
-        <groupId>org.apache.servicecomb.saga</groupId>
-        <artifactId>saga-persistence-jpa</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
+       <groupId>org.apache.servicecomb.saga</groupId>
+       <artifactId>saga-persistence-jpa</artifactId>
+       <version>0.0.3-SNAPSHOT</version>
+       </dependency>
       <dependency>
         <groupId>commons-io</groupId>
         <artifactId>commons-io</artifactId>
diff --git a/saga-core/pom.xml b/saga-core/pom.xml
deleted file mode 100644
index f9ba4264..00000000
--- a/saga-core/pom.xml
+++ /dev/null
@@ -1,103 +0,0 @@
-<?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</artifactId>
-    <groupId>org.apache.servicecomb.saga</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>saga-core</artifactId>
-  <name>Saga::Core</name>
-
-  <dependencies>
-    <dependency>
-      <groupId>com.lmax</groupId>
-      <artifactId>disruptor</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-slf4j-impl</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.typesafe.akka</groupId>
-      <artifactId>akka-actor_2.12</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.typesafe.akka</groupId>
-      <artifactId>akka-slf4j_2.12</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.kamon</groupId>
-      <artifactId>kamon-core_2.12</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.kamon</groupId>
-      <artifactId>kamon-annotation_2.12</artifactId>
-    </dependency>
-
-    <!-- test dependencies -->
-    <dependency>
-      <groupId>com.typesafe.akka</groupId>
-      <artifactId>akka-testkit_2.12</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.scalatest</groupId>
-      <artifactId>scalatest_2.12</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.hamcrest</groupId>
-      <artifactId>hamcrest-all</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-lang3</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.awaitility</groupId>
-      <artifactId>awaitility</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.github.seanyinx</groupId>
-      <artifactId>unit-scaffolding</artifactId>
-    </dependency>
-  </dependencies>
-
-</project>
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/BackwardRecovery.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/BackwardRecovery.java
deleted file mode 100644
index e46de2fa..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/BackwardRecovery.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.core;
-
-import java.lang.invoke.MethodHandles;
-import kamon.annotation.EnableKamon;
-import kamon.annotation.Segment;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-@EnableKamon
-public class BackwardRecovery implements RecoveryPolicy {
-
-  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-  @Segment(name = "backwardPolicy", category = "application", library = "kamon")
-  @Override
-  public SagaResponse apply(SagaTask task, SagaRequest request, SagaResponse parentResponse) {
-    try {
-      return request.transaction().send(request.serviceName(), parentResponse);
-    } catch (Exception e) {
-      log.error("Applying {} policy due to failure in transaction {} of service {}",
-          description(),
-          request.transaction(),
-          request.serviceName(),
-          e
-      );
-
-      task.abort(request, e);
-      throw e;
-    }
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/Compensation.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/Compensation.java
deleted file mode 100644
index f642011a..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/Compensation.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.core;
-
-public interface Compensation extends Operation {
-
-  Compensation SAGA_START_COMPENSATION = new Compensation() {
-  };
-
-  Compensation SAGA_END_COMPENSATION = new Compensation() {
-  };
-
-  int DEFAULT_RETRIES = 3;
-
-  default int retries() {
-    return DEFAULT_RETRIES;
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/CompensationTaskConsumer.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/CompensationTaskConsumer.java
deleted file mode 100644
index 736c34d0..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/CompensationTaskConsumer.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.core;
-
-import java.lang.invoke.MethodHandles;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.apache.servicecomb.saga.core.dag.Node;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class CompensationTaskConsumer implements TaskConsumer {
-
-  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-  private final Map<String, SagaTask> tasks;
-  private final SagaContext sagaContext;
-
-  CompensationTaskConsumer(Map<String, SagaTask> tasks, SagaContext sagaContext) {
-    this.tasks = tasks;
-    this.sagaContext = sagaContext;
-  }
-
-  @Override
-  public void consume(Collection<Node<SagaRequest>> nodes) {
-    for (Node<SagaRequest> node : nodes) {
-      SagaRequest request = node.value();
-
-      if (sagaContext.isTransactionCompleted(request)) {
-        log.info("Starting request {} id={}", request.serviceName(), request.id());
-        tasks.get(request.task()).compensate(request);
-        log.info("Completed request {} id={}", request.serviceName(), request.id());
-      }
-    }
-  }
-
-  @Override
-  public boolean replay(Collection<Node<SagaRequest>> nodes) {
-
-    for (Iterator<Node<SagaRequest>> iterator = nodes.iterator(); iterator.hasNext(); ) {
-      SagaRequest request = iterator.next().value();
-      if (sagaContext.isCompensationCompleted(request)) {
-        log.info("Skipped completed compensation id={} operation={} while replay", request.id(), request.transaction());
-        iterator.remove();
-      } else if (!sagaContext.isTransactionCompleted(request)) {
-        // this transaction never started
-        log.info("Skipped pending transaction id={} operation={} while replay", request.id(), request.transaction());
-        iterator.remove();
-      }
-    }
-    return !nodes.isEmpty();
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/CompositeSagaLog.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/CompositeSagaLog.java
deleted file mode 100644
index 017129aa..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/CompositeSagaLog.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.core;
-
-import kamon.annotation.EnableKamon;
-import kamon.annotation.Segment;
-
-@EnableKamon
-class CompositeSagaLog implements SagaLog {
-
-  private final SagaLog embedded;
-  private final PersistentLog persistent;
-
-  CompositeSagaLog(SagaLog embedded, PersistentLog persistent) {
-    this.embedded = embedded;
-    this.persistent = persistent;
-  }
-
-  @Segment(name = "compositeSagaLog", category = "application", library = "kamon")
-  @Override
-  public void offer(SagaEvent sagaEvent) {
-    persistent.offer(sagaEvent);
-    embedded.offer(sagaEvent);
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/CompositeSagaResponse.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/CompositeSagaResponse.java
deleted file mode 100644
index 02ab48c8..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/CompositeSagaResponse.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.core;
-
-import java.util.Collection;
-import java.util.Optional;
-
-public class CompositeSagaResponse implements SagaResponse {
-  private final Collection<SagaResponse> responses;
-
-  public CompositeSagaResponse(Collection<SagaResponse> responses) {
-    this.responses = responses;
-  }
-
-  @Override
-  public boolean succeeded() {
-    return responses.stream().allMatch(SagaResponse::succeeded);
-  }
-
-  @Override
-  public String body() {
-    Optional<String> reduce = responses.stream()
-        .map(SagaResponse::body)
-        .reduce((a, b) -> a + ", " + b)
-        .map(combined -> "[" + combined + "]");
-
-    return reduce.orElse("{}");
-  }
-
-  public Collection<SagaResponse> responses() {
-    return responses;
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/Descriptive.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/Descriptive.java
deleted file mode 100644
index bd367af8..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/Descriptive.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.core;
-
-interface Descriptive {
-
-  default String description() {
-    return getClass().getSimpleName();
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/EventContext.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/EventContext.java
deleted file mode 100644
index 79b0c3e4..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/EventContext.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.core;
-
-public interface EventContext {
-  void beginTransaction(SagaRequest request);
-
-  void endTransaction(SagaRequest request, SagaResponse response);
-
-  void abortTransaction(SagaRequest request, SagaResponse response);
-
-  void compensateTransaction(SagaRequest request, SagaResponse response);
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/EventEnvelope.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/EventEnvelope.java
deleted file mode 100644
index 9283b33e..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/EventEnvelope.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.core;
-
-public class EventEnvelope {
-
-  public final long id;
-  public final long timestamp;
-  public final SagaEvent event;
-
-  public EventEnvelope(long id, SagaEvent event) {
-    this.id = id;
-    this.event = event;
-    this.timestamp = System.currentTimeMillis();
-  }
-
-  // TODO: 8/21/2017 this class seems to be useless to saga
-  public EventEnvelope(long id, long timestamp, SagaEvent event) {
-    this.id = id;
-    this.timestamp = timestamp;
-    this.event = event;
-  }
-
-  @Override
-  public String toString() {
-    return "EventEnvelope{" +
-        "id=" + id +
-        ", timestamp=" + timestamp +
-        ", event={" + event +
-        "}}";
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/EventStore.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/EventStore.java
deleted file mode 100644
index 7b7e6e24..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/EventStore.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.core;
-
-public interface EventStore extends SagaLog, Iterable<SagaEvent> {
-
-  void populate(Iterable<EventEnvelope> events);
-
-  long size();
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/FailedSagaResponse.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/FailedSagaResponse.java
deleted file mode 100644
index 15d1701d..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/FailedSagaResponse.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.core;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-public class FailedSagaResponse implements SagaResponse {
-
-  private final String body;
-
-  public FailedSagaResponse(String body) {
-    this.body = body;
-  }
-
-  public FailedSagaResponse(Throwable e) {
-    this.body = stackTrace(e);
-  }
-
-  @Override
-  public boolean succeeded() {
-    return false;
-  }
-
-  @Override
-  public String body() {
-    return body;
-  }
-
-  private String stackTrace(Throwable e) {
-    StringWriter writer = new StringWriter();
-    e.printStackTrace(new PrintWriter(writer));
-    return writer.toString();
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/Fallback.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/Fallback.java
deleted file mode 100644
index fca68a03..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/Fallback.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.core;
-
-public interface Fallback extends Operation {
-
-  Fallback NOP_FALLBACK = () -> TYPE_NOP;
-
-  String type();
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/FallbackPolicy.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/FallbackPolicy.java
deleted file mode 100644
index 48ad67de..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/FallbackPolicy.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.core;
-
-import java.lang.invoke.MethodHandles;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class FallbackPolicy {
-  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-  private final int retryDelay;
-
-  public FallbackPolicy(int retryDelay) {
-    this.retryDelay = retryDelay;
-  }
-
-  public SagaResponse apply(String address, Compensation compensation, Fallback fallback) {
-    for (int i = 0; isRetryable(i, compensation) && !isInterrupted(); i++) {
-      try {
-        return compensation.send(address);
-      } catch (Exception e) {
-        log.error("Failed to send compensation to {}", address, e);
-        sleep(retryDelay);
-      }
-    }
-
-    log.warn("Falling back after {} failures sending compensation to {}", compensation.retries(), address);
-    return fallback.send(address);
-  }
-
-  private boolean isRetryable(int i, Compensation compensation) {
-    return compensation.retries() < 0 || i <= compensation.retries();
-  }
-
-  private boolean isInterrupted() {
-    return Thread.currentThread().isInterrupted();
-  }
-
-  private void sleep(int delay) {
-    try {
-      Thread.sleep(delay);
-    } catch (InterruptedException ignored) {
-      Thread.currentThread().interrupt();
-    }
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/ForwardRecovery.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/ForwardRecovery.java
deleted file mode 100644
index c783990f..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/ForwardRecovery.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.core;
-
-import java.lang.invoke.MethodHandles;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ForwardRecovery implements RecoveryPolicy {
-
-  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-  @Override
-  public SagaResponse apply(SagaTask task, SagaRequest request, SagaResponse parentResponse) {
-    try {
-      do {
-        try {
-          return request.transaction().send(request.serviceName(), parentResponse);
-        } catch (Exception e) {
-          log.error("Applying {} policy due to failure in transaction {} of service {}",
-              description(),
-              request.transaction(),
-              request.serviceName(),
-              e
-          );
-          Thread.sleep(request.failRetryDelayMilliseconds());
-        }
-      } while (true);
-    } catch (InterruptedException ignored) {
-      log.warn("Applying {} interrupted in transaction {} of service {}",
-          description(),
-          request.transaction(),
-          request.serviceName(),
-          ignored);
-      throw new TransactionFailedException(ignored);
-    }
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/GraphBasedSaga.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/GraphBasedSaga.java
deleted file mode 100644
index f4544e3a..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/GraphBasedSaga.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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.core;
-
-import java.lang.invoke.MethodHandles;
-import java.util.Map;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorCompletionService;
-import java.util.concurrent.Executors;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.servicecomb.saga.core.dag.ByLevelTraveller;
-import org.apache.servicecomb.saga.core.dag.FromLeafTraversalDirection;
-import org.apache.servicecomb.saga.core.dag.FromRootTraversalDirection;
-import org.apache.servicecomb.saga.core.dag.SingleLeafDirectedAcyclicGraph;
-import org.apache.servicecomb.saga.core.dag.TraversalDirection;
-import kamon.annotation.EnableKamon;
-import kamon.annotation.Segment;
-
-@EnableKamon
-public class GraphBasedSaga implements Saga {
-
-  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-  private final EventStore eventStore;
-  private final Map<String, SagaTask> tasks;
-
-  private final TaskRunner transactionTaskRunner;
-  private final TaskRunner compensationTaskRunner;
-  private final SagaContext sagaContext;
-  private volatile SagaState currentTaskRunner;
-
-  GraphBasedSaga(EventStore eventStore,
-      Map<String, SagaTask> tasks,
-      SagaContext sagaContext,
-      SingleLeafDirectedAcyclicGraph<SagaRequest> sagaTaskGraph) {
-
-    this(eventStore, Executors.newFixedThreadPool(5), tasks, sagaContext, sagaTaskGraph);
-  }
-
-  public GraphBasedSaga(EventStore eventStore,
-      Executor executor,
-      Map<String, SagaTask> tasks,
-      SagaContext sagaContext,
-      SingleLeafDirectedAcyclicGraph<SagaRequest> sagaTaskGraph) {
-
-    this.eventStore = eventStore;
-    this.tasks = tasks;
-
-    this.transactionTaskRunner = new TaskRunner(
-        traveller(sagaTaskGraph, new FromRootTraversalDirection<>()),
-        new TransactionTaskConsumer(
-            tasks,
-            sagaContext,
-            new ExecutorCompletionService<>(executor)));
-
-    this.sagaContext = sagaContext;
-    this.compensationTaskRunner = new TaskRunner(
-        traveller(sagaTaskGraph, new FromLeafTraversalDirection<>()),
-        new CompensationTaskConsumer(tasks, sagaContext));
-
-    currentTaskRunner = transactionTaskRunner;
-  }
-
-  @Override
-  @Segment(name = "runSaga", category = "application", library = "kamon")
-  public SagaResponse run() {
-    SagaResponse response = SagaResponse.EMPTY_RESPONSE;
-    log.info("Starting Saga");
-    do {
-      try {
-        currentTaskRunner.run();
-      } catch (TransactionFailedException e) {
-        response = new FailedSagaResponse(e);
-        log.error("Failed to run operation", e);
-        currentTaskRunner = compensationTaskRunner;
-
-        sagaContext.handleHangingTransactions(request -> {
-          tasks.get(request.task()).commit(request, sagaContext.responseOf(request.parents()));
-          tasks.get(request.task()).compensate(request);
-        });
-      }
-    } while (currentTaskRunner.hasNext());
-    log.info("Completed Saga");
-    return response;
-  }
-
-  @Override
-  public void play() {
-    log.info("Start playing events");
-    gatherEvents(eventStore);
-
-    transactionTaskRunner.replay();
-
-    if (sagaContext.isCompensationStarted()) {
-      currentTaskRunner = compensationTaskRunner;
-      compensationTaskRunner.replay();
-    }
-
-    log.info("Completed playing events");
-  }
-
-  private void gatherEvents(Iterable<SagaEvent> events) {
-    for (SagaEvent event : events) {
-      event.gatherTo(sagaContext);
-    }
-  }
-
-  private ByLevelTraveller<SagaRequest> traveller(
-      SingleLeafDirectedAcyclicGraph<SagaRequest> sagaTaskGraph,
-      TraversalDirection<SagaRequest> traversalDirection) {
-
-    return new ByLevelTraveller<>(sagaTaskGraph, traversalDirection);
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/IdGenerator.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/IdGenerator.java
deleted file mode 100644
index 2add2603..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/IdGenerator.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.core;
-
-import java.io.Serializable;
-
-public interface IdGenerator<T extends Serializable> {
-
-  T nextId();
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/LoggingRecoveryPolicy.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/LoggingRecoveryPolicy.java
deleted file mode 100644
index 9173ecad..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/LoggingRecoveryPolicy.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.core;
-
-import java.lang.invoke.MethodHandles;
-import kamon.annotation.EnableKamon;
-import kamon.annotation.Segment;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-
-@EnableKamon
-public class LoggingRecoveryPolicy implements RecoveryPolicy {
-  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-  private final RecoveryPolicy recoveryPolicy;
-
-  public LoggingRecoveryPolicy(RecoveryPolicy recoveryPolicy) {
-    this.recoveryPolicy = recoveryPolicy;
-  }
-
-  @Segment(name = "loggingPolicy", category = "application", library = "kamon")
-  @Override
-  public SagaResponse apply(SagaTask task, SagaRequest request, SagaResponse parentResponse) {
-    log.info("Starting request id={} for service {}", request.id(), request.serviceName());
-    SagaResponse response = recoveryPolicy.apply(task, request, parentResponse);
-    log.info("Completed request id={} for service {}", request.id(), request.serviceName());
-    return response;
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/LongIdGenerator.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/LongIdGenerator.java
deleted file mode 100644
index 6b16075b..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/LongIdGenerator.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.core;
-
-import java.util.concurrent.atomic.AtomicLong;
-
-public class LongIdGenerator implements IdGenerator<Long> {
-
-  private final AtomicLong atomicLong = new AtomicLong();
-
-  @Override
-  public Long nextId() {
-    return atomicLong.incrementAndGet();
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/NoOpSagaRequest.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/NoOpSagaRequest.java
deleted file mode 100644
index 56ad05ee..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/NoOpSagaRequest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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.core;
-
-import static org.apache.servicecomb.saga.core.Compensation.SAGA_END_COMPENSATION;
-import static org.apache.servicecomb.saga.core.Compensation.SAGA_START_COMPENSATION;
-import static org.apache.servicecomb.saga.core.Operation.TYPE_NOP;
-import static org.apache.servicecomb.saga.core.SagaTask.SAGA_END_TASK;
-import static org.apache.servicecomb.saga.core.SagaTask.SAGA_START_TASK;
-import static org.apache.servicecomb.saga.core.Transaction.SAGA_END_TRANSACTION;
-import static org.apache.servicecomb.saga.core.Transaction.SAGA_START_TRANSACTION;
-
-import java.util.Arrays;
-
-public class NoOpSagaRequest implements SagaRequest {
-
-  public static final SagaRequest SAGA_START_REQUEST = new NoOpSagaRequest(
-      "saga-start",
-      SAGA_START_TRANSACTION,
-      SAGA_START_COMPENSATION,
-      SAGA_START_TASK);
-
-  public static final SagaRequest SAGA_END_REQUEST = new NoOpSagaRequest(
-      "saga-end",
-      SAGA_END_TRANSACTION,
-      SAGA_END_COMPENSATION,
-      SAGA_END_TASK);
-
-  private final String id;
-  private final Transaction transaction;
-  private final Compensation compensation;
-  private final String task;
-  private final String[] parents = {};
-
-  private NoOpSagaRequest(String id, Transaction transaction, Compensation compensation, String task) {
-    this.id = id;
-    this.transaction = transaction;
-    this.compensation = compensation;
-    this.task = task;
-  }
-
-  @Override
-  public Transaction transaction() {
-    return transaction;
-  }
-
-  @Override
-  public Compensation compensation() {
-    return compensation;
-  }
-
-  @Override
-  public String serviceName() {
-    return "Saga";
-  }
-
-  @Override
-  public String id() {
-    return id;
-  }
-
-  @Override
-  public String type() {
-    return TYPE_NOP;
-  }
-
-  @Override
-  public String task() {
-    return task;
-  }
-
-  @Override
-  public String[] parents() {
-    return parents;
-  }
-
-  @Override
-  public int failRetryDelayMilliseconds() {
-    return 50;
-  }
-
-  @Override
-  public String toString() {
-    return "NoOpSagaRequest{" +
-        "id='" + id + '\'' +
-        ", transaction=" + transaction +
-        ", compensation=" + compensation +
-        ", task='" + task + '\'' +
-        ", parents=" + Arrays.toString(parents) +
-        '}';
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/Operation.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/Operation.java
deleted file mode 100644
index 13b6f8ab..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/Operation.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.core;
-
-public interface Operation {
-
-  String TYPE_NOP = "NOP";
-  String TYPE_REST = "rest";
-  SagaResponse SUCCESSFUL_SAGA_RESPONSE = new SuccessfulSagaResponse("success");
-
-  default SagaResponse send(String address) {
-    return SUCCESSFUL_SAGA_RESPONSE;
-  }
-
-  default SagaResponse send(String address, SagaResponse response) {
-    return send(address);
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/PersistentLog.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/PersistentLog.java
deleted file mode 100644
index 26ec4bcb..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/PersistentLog.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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.core;
-
-public interface PersistentLog {
-  void offer(SagaEvent sagaEvent);
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/PersistentStore.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/PersistentStore.java
deleted file mode 100644
index a7620b3c..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/PersistentStore.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.core;
-
-import java.util.List;
-import java.util.Map;
-
-public interface PersistentStore extends PersistentLog {
-
-  Map<String, List<EventEnvelope>> findPendingSagaEvents();
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/RecoveryPolicy.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/RecoveryPolicy.java
deleted file mode 100644
index c67d6404..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/RecoveryPolicy.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.core;
-
-public interface RecoveryPolicy extends Descriptive {
-
-  String SAGA_FORWARD_RECOVERY_POLICY = "ForwardRecovery";
-  String SAGA_BACKWARD_RECOVERY_POLICY = "BackwardRecovery";
-
-  SagaResponse apply(SagaTask task, SagaRequest request, SagaResponse parentResponse);
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/RequestProcessTask.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/RequestProcessTask.java
deleted file mode 100644
index e19c7bf4..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/RequestProcessTask.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.core;
-
-import kamon.annotation.EnableKamon;
-import kamon.annotation.Segment;
-
-@EnableKamon
-public class RequestProcessTask implements SagaTask {
-
-  private final String sagaId;
-  private final SagaLog sagaLog;
-  private final RecoveryPolicy recoveryPolicy;
-  private final FallbackPolicy fallbackPolicy;
-
-  public RequestProcessTask(
-      String sagaId,
-      SagaLog sagaLog,
-      RecoveryPolicy recoveryPolicy,
-      FallbackPolicy fallbackPolicy) {
-
-    this.sagaId = sagaId;
-    this.sagaLog = sagaLog;
-    this.recoveryPolicy = recoveryPolicy;
-    this.fallbackPolicy = fallbackPolicy;
-  }
-
-  @Segment(name = "commit", category = "application", library = "kamon")
-  @Override
-  public SagaResponse commit(SagaRequest request, SagaResponse parentResponse) {
-    sagaLog.offer(new TransactionStartedEvent(sagaId, request));
-
-    SagaResponse response = recoveryPolicy.apply(this, request, parentResponse);
-
-    sagaLog.offer(new TransactionEndedEvent(sagaId, request, response));
-    return response;
-  }
-
-  @Segment(name = "compensate", category = "application", library = "kamon")
-  @Override
-  public void compensate(SagaRequest request) {
-    Compensation compensation = request.compensation();
-    SagaResponse response = fallbackPolicy.apply(request.serviceName(), compensation, request.fallback());
-
-    sagaLog.offer(new TransactionCompensatedEvent(sagaId, request, response));
-  }
-
-  @Override
-  public void abort(SagaRequest request, Exception e) {
-    sagaLog.offer(new TransactionAbortedEvent(sagaId, request, e));
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/RestOperation.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/RestOperation.java
deleted file mode 100644
index 5cce22de..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/RestOperation.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.core;
-
-import static java.util.Collections.emptyMap;
-
-import org.apache.servicecomb.saga.core.application.interpreter.RestRequestChecker;
-import java.util.Map;
-
-public class RestOperation implements Operation {
-
-  private final String path;
-  private final String method;
-  private final Map<String, Map<String, String>> params;
-
-  public RestOperation(String path, String method, Map<String, Map<String, String>> params) {
-    RestRequestChecker.checkParameters(method, params);
-
-    this.path = path;
-    this.method = method;
-    this.params = params == null? emptyMap() : params;
-  }
-
-  public String path() {
-    return path;
-  }
-
-  public String method() {
-    return method;
-  }
-
-  public Map<String, Map<String, String>> params() {
-    return params;
-  }
-
-  @Override
-  public String toString() {
-    return "Operation{" +
-        "path='" + path + '\'' +
-        ", method='" + method + '\'' +
-        ", params=" + params +
-        '}';
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/Saga.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/Saga.java
deleted file mode 100644
index 44f62ea5..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/Saga.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.core;
-
-import kamon.annotation.Segment;
-
-public interface Saga {
-  @Segment(name = "runSaga", category = "application", library = "kamon")
-  SagaResponse run();
-
-  void play();
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaContext.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaContext.java
deleted file mode 100644
index 309be446..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaContext.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.core;
-
-import java.util.function.Consumer;
-
-public interface SagaContext extends EventContext {
-  boolean isCompensationStarted();
-
-  boolean isTransactionCompleted(SagaRequest request);
-
-  boolean isCompensationCompleted(SagaRequest request);
-
-  void handleHangingTransactions(Consumer<SagaRequest> consumer);
-
-  SagaResponse responseOf(String requestId);
-
-  boolean isChosenChild(SagaRequest request);
-
-  SagaResponse responseOf(String[] parentRequestIds);
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaContextImpl.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaContextImpl.java
deleted file mode 100644
index 610ae274..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaContextImpl.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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.core;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentSkipListSet;
-import java.util.function.Consumer;
-import java.util.stream.Collectors;
-
-import org.apache.servicecomb.saga.core.application.interpreter.FromJsonFormat;
-
-public class SagaContextImpl implements SagaContext {
-
-  private final Map<String, SagaResponse> completedTransactions;
-  private final Map<String, SagaResponse> completedCompensations;
-  private final Set<String> abortedTransactions;
-  private final Map<String, SagaRequest> hangingTransactions;
-  private final FromJsonFormat<Set<String>> childrenExtractor;
-
-  public SagaContextImpl(FromJsonFormat<Set<String>> childrenExtractor) {
-    this.childrenExtractor = childrenExtractor;
-    this.completedTransactions = new ConcurrentHashMap<>();
-    this.completedCompensations = new HashMap<>();
-    this.abortedTransactions = new ConcurrentSkipListSet<>();
-    this.hangingTransactions = new ConcurrentHashMap<>();
-  }
-
-  @Override
-  public boolean isCompensationStarted() {
-    return !abortedTransactions.isEmpty() || !completedCompensations.isEmpty();
-  }
-
-  @Override
-  public boolean isTransactionCompleted(SagaRequest request) {
-    return completedTransactions.containsKey(request.id());
-  }
-
-  @Override
-  public boolean isCompensationCompleted(SagaRequest request) {
-    return completedCompensations.containsKey(request.id());
-  }
-
-  @Override
-  public void beginTransaction(SagaRequest request) {
-    hangingTransactions.put(request.id(), request);
-  }
-
-  @Override
-  public void endTransaction(SagaRequest request, SagaResponse response) {
-    completedTransactions.put(request.id(), response);
-    hangingTransactions.remove(request.id());
-  }
-
-  @Override
-  public void abortTransaction(SagaRequest request, SagaResponse response) {
-    completedTransactions.remove(request.id());
-    abortedTransactions.add(request.id());
-    hangingTransactions.remove(request.id());
-  }
-
-  @Override
-  public void compensateTransaction(SagaRequest request, SagaResponse response) {
-    completedCompensations.put(request.id(), response);
-    completedTransactions.remove(request.id());
-  }
-
-  @Override
-  public void handleHangingTransactions(Consumer<SagaRequest> consumer)  {
-    for (Iterator<SagaRequest> iterator = hangingTransactions.values().iterator(); iterator.hasNext(); ) {
-      consumer.accept(iterator.next());
-    }
-  }
-
-  @Override
-  public SagaResponse responseOf(String requestId) {
-    return completedTransactions.getOrDefault(requestId, SagaResponse.NONE_RESPONSE);
-  }
-
-  private List<SagaResponse> responsesOf(String[] parentRequestIds) {
-    return Arrays.stream(parentRequestIds)
-        .map(this::responseOf)
-        .collect(Collectors.toList());
-  }
-
-  @Override
-  public SagaResponse responseOf(String[] parentRequestIds) {
-    List<SagaResponse> responses = responsesOf(parentRequestIds);
-
-    if (responses.isEmpty()) {
-      return SagaResponse.EMPTY_RESPONSE;
-    }
-
-    if (responses.size() == 1) {
-      return responses.get(0);
-    }
-
-    return new CompositeSagaResponse(responses);
-  }
-
-  @Override
-  public boolean isChosenChild(SagaRequest request)  {
-    Set<String> chosenChildren = chosenChildrenOf(request.parents());
-    return chosenChildren.isEmpty() || chosenChildren.contains(request.id());
-  }
-
-  private Set<String> chosenChildrenOf(String[] parentRequestIds) {
-    return Arrays.stream(parentRequestIds)
-        .map(this::responseOf)
-        .flatMap(sagaResponse -> childrenExtractor.fromJson(sagaResponse.body()).stream())
-        .collect(Collectors.toSet());
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaDefinition.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaDefinition.java
deleted file mode 100644
index 406c8df5..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaDefinition.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.core;
-
-public interface SagaDefinition {
-
-  RecoveryPolicy policy();
-
-  SagaRequest[] requests();
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaEndTask.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaEndTask.java
deleted file mode 100644
index 69daba7d..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaEndTask.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.core;
-
-import kamon.annotation.EnableKamon;
-import kamon.annotation.Segment;
-
-@EnableKamon
-public class SagaEndTask implements SagaTask {
-
-  private final String sagaId;
-  private final SagaLog sagaLog;
-
-  public SagaEndTask(String sagaId, SagaLog sagaLog) {
-    this.sagaId = sagaId;
-    this.sagaLog = sagaLog;
-  }
-
-  @Segment(name = "endTaskCommit", category = "application", library = "kamon")
-  @Override
-  public SagaResponse commit(SagaRequest request, SagaResponse parentResponse) {
-    sagaLog.offer(new SagaEndedEvent(sagaId, request));
-    return SagaResponse.EMPTY_RESPONSE;
-  }
-
-  @Override
-  public void compensate(SagaRequest request) {
-  }
-
-  @Override
-  public void abort(SagaRequest request, Exception e) {
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaEndedEvent.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaEndedEvent.java
deleted file mode 100644
index c6f4f9f0..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaEndedEvent.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.core;
-
-public class SagaEndedEvent extends SagaEvent {
-
-  public SagaEndedEvent(String sagaId, SagaRequest sagaTask) {
-    super(sagaId, sagaTask);
-  }
-
-  @Override
-  public void gatherTo(EventContext sagaContext) {
-    sagaContext.endTransaction(payload(), SagaResponse.EMPTY_RESPONSE);
-  }
-
-  @Override
-  public String toString() {
-    return "SagaEndedEvent{id="
-        + payload().id()
-        + ", sagaId=" + sagaId
-        + "}";
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaEvent.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaEvent.java
deleted file mode 100644
index ceb0ebe7..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaEvent.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.core;
-
-public abstract class SagaEvent implements Descriptive {
-
-  public final String sagaId;
-  private final SagaRequest payload;
-
-  public SagaEvent(String sagaId, SagaRequest payload) {
-    this.sagaId = sagaId;
-    this.payload = payload;
-  }
-
-  public SagaRequest payload() {
-    return payload;
-  }
-
-  public abstract void gatherTo(EventContext sagaContext);
-
-  public String json(ToJsonFormat toJsonFormat) {
-    return "{}";
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaException.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaException.java
deleted file mode 100644
index 49ce9890..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.core;
-
-public class SagaException extends RuntimeException {
-
-  public SagaException(String cause, Throwable e) {
-    super(cause, e);
-  }
-
-  public SagaException(String cause) {
-    super(cause);
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaLog.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaLog.java
deleted file mode 100644
index 2e07b9f6..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaLog.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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.core;
-
-public interface SagaLog extends PersistentLog {
-
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaRequest.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaRequest.java
deleted file mode 100644
index 337abdde..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaRequest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.core;
-
-import static org.apache.servicecomb.saga.core.Fallback.NOP_FALLBACK;
-
-public interface SagaRequest {
-
-  String PARAM_FORM = "form";
-  String PARAM_JSON = "json";
-  String PARAM_JSON_BODY = "body";
-  String PARAM_QUERY = "query";
-
-  Transaction transaction();
-
-  Compensation compensation();
-
-  default Fallback fallback() {
-    return NOP_FALLBACK;
-  }
-
-  String serviceName();
-
-  String id();
-
-  String type();
-
-  String task();
-
-  String[] parents();
-
-  int failRetryDelayMilliseconds();
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaRequestImpl.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaRequestImpl.java
deleted file mode 100644
index cbb7a230..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaRequestImpl.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * 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.core;
-
-import static org.apache.servicecomb.saga.core.Fallback.NOP_FALLBACK;
-
-import java.util.Arrays;
-
-public class SagaRequestImpl implements SagaRequest {
-
-  private final String id;
-  private final String serviceName;
-  private final String type;
-  private final Transaction transaction;
-  private final Compensation compensation;
-  private final String[] parents;
-  private final Fallback fallback;
-  private final int failRetryDelayMilliseconds;
-
-  public SagaRequestImpl(
-      String id,
-      String serviceName,
-      String type,
-      Transaction transaction,
-      Compensation compensation,
-      Fallback fallback,
-      String[] parents,
-      int failRetryDelayMilliseconds) {
-
-    this.id = id;
-    this.serviceName = serviceName;
-    this.type = type;
-    this.transaction = transaction;
-    this.compensation = compensation;
-    this.fallback = fallback;
-    this.failRetryDelayMilliseconds = failRetryDelayMilliseconds <= 0 ? 50 : failRetryDelayMilliseconds;
-    // TODO: 2017/10/21 set parent to root when null
-    this.parents = parents == null ? new String[0] : parents;
-  }
-
-  public SagaRequestImpl(
-      String id,
-      String serviceName,
-      String type,
-      Transaction transaction,
-      Compensation compensation,
-      Fallback fallback,
-      String[] parents) {
-    this(id, serviceName, type, transaction, compensation, fallback, parents, 0);
-  }
-
-  public SagaRequestImpl(
-      String id,
-      String serviceName,
-      String type,
-      Transaction transaction,
-      Compensation compensation,
-      Fallback fallback) {
-    this(id, serviceName, type, transaction, compensation, fallback, new String[0]);
-  }
-
-  public SagaRequestImpl(
-      String id,
-      String serviceName,
-      String type,
-      Transaction transaction,
-      Compensation compensation) {
-    this(id, serviceName, type, transaction, compensation, NOP_FALLBACK, new String[0]);
-  }
-
-  public SagaRequestImpl(
-      String id,
-      String serviceName,
-      String type,
-      Transaction transaction,
-      Compensation compensation,
-      String[] parents) {
-    this(id, serviceName, type, transaction, compensation, NOP_FALLBACK, parents);
-  }
-
-  @Override
-  public Transaction transaction() {
-    return transaction;
-  }
-
-  @Override
-  public Compensation compensation() {
-    return compensation;
-  }
-
-  @Override
-  public Fallback fallback() {
-    return fallback;
-  }
-
-  @Override
-  public String serviceName() {
-    return serviceName;
-  }
-
-  @Override
-  public String id() {
-    return id;
-  }
-
-  @Override
-  public String type() {
-    return type;
-  }
-
-  @Override
-  public String task() {
-    return SagaTask.SAGA_REQUEST_TASK;
-  }
-
-  @Override
-  public String[] parents() {
-    return parents;
-  }
-
-  @Override
-  public int failRetryDelayMilliseconds() {
-    return failRetryDelayMilliseconds;
-  }
-
-  @Override
-  public String toString() {
-    return "SagaRequest{" +
-        "id='" + id + '\'' +
-        ", serviceName='" + serviceName + '\'' +
-        ", type='" + type + '\'' +
-        ", transaction=" + transaction +
-        ", compensation=" + compensation +
-        ", fallback=" + fallback +
-        ", parents=" + Arrays.toString(parents) +
-        '}';
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaResponse.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaResponse.java
deleted file mode 100644
index ecdfe4a0..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaResponse.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.core;
-
-public interface SagaResponse {
-
-  SagaResponse EMPTY_RESPONSE = new SagaResponse() {
-    @Override
-    public boolean succeeded() {
-      return true;
-    }
-
-    @Override
-    public String body() {
-      return "{}";
-    }
-
-    @Override
-    public String toString() {
-      return "EMPTY_RESPONSE{body={}}";
-    }
-  };
-
-  SagaResponse NONE_RESPONSE = new SagaResponse() {
-    @Override
-    public boolean succeeded() {
-      return false;
-    }
-
-    @Override
-    public String body() {
-      return "{\n"
-          + "  \"sagaChildren\": [\"none\"]\n"
-          + "}";
-    }
-
-    @Override
-    public String toString() {
-      return "NONE_RESPONSE{body={\"sagaChildren\": [\"none\"]\n}}";
-    }
-  };
-
-  boolean succeeded();
-
-  String body();
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaStartFailedException.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaStartFailedException.java
deleted file mode 100644
index 0de35da0..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaStartFailedException.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.core;
-
-public class SagaStartFailedException extends RuntimeException {
-
-  public SagaStartFailedException(String cause, Throwable e) {
-    super(cause, e);
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaStartTask.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaStartTask.java
deleted file mode 100644
index d8a6bd12..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaStartTask.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.core;
-
-import kamon.annotation.EnableKamon;
-import kamon.annotation.Segment;
-
-@EnableKamon
-public class SagaStartTask implements SagaTask {
-
-  private final String sagaId;
-  private final String requestJson;
-  private final SagaLog sagaLog;
-
-  public SagaStartTask(String sagaId, String requestJson, SagaLog sagaLog) {
-    this.sagaId = sagaId;
-    this.requestJson = requestJson;
-    this.sagaLog = sagaLog;
-  }
-
-  @Segment(name = "startTaskCommit", category = "application", library = "kamon")
-  @Override
-  public SagaResponse commit(SagaRequest request, SagaResponse parentResponse) {
-    try {
-      sagaLog.offer(new SagaStartedEvent(sagaId, requestJson, request));
-    } catch (Exception e) {
-      throw new SagaStartFailedException("Failed to persist SagaStartedEvent for " + requestJson, e);
-    }
-    return SagaResponse.EMPTY_RESPONSE;
-  }
-
-  @Override
-  public void compensate(SagaRequest request) {
-    sagaLog.offer(new SagaEndedEvent(sagaId, request));
-  }
-
-  @Override
-  public void abort(SagaRequest request, Exception e) {
-
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaStartedEvent.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaStartedEvent.java
deleted file mode 100644
index 0d82feed..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaStartedEvent.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.core;
-
-public class SagaStartedEvent extends SagaEvent {
-
-  private final String requestJson;
-
-  public SagaStartedEvent(String sagaId, String requestJson, SagaRequest request) {
-    super(sagaId, request);
-    this.requestJson = requestJson;
-  }
-
-  @Override
-  public void gatherTo(EventContext sagaContext) {
-    sagaContext.endTransaction(payload(), SagaResponse.EMPTY_RESPONSE);
-  }
-
-  @Override
-  public String json(ToJsonFormat toJsonFormat) {
-    return requestJson;
-  }
-
-  @Override
-  public String toString() {
-    return "SagaStartedEvent{id="
-        + payload().id()
-        + ", sagaId=" + sagaId
-        + "}";
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaState.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaState.java
deleted file mode 100644
index eae3678e..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaState.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.core;
-
-interface SagaState {
-
-  boolean hasNext();
-
-  void run();
-
-  void replay();
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaTask.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaTask.java
deleted file mode 100644
index 73efcc0c..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaTask.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.core;
-
-public interface SagaTask {
-
-  String SAGA_START_TASK = "SagaStart";
-  String SAGA_REQUEST_TASK = "SagaRequest";
-  String SAGA_END_TASK = "SagaEnd";
-
-  SagaResponse commit(SagaRequest request, SagaResponse parentResponse);
-
-  void compensate(SagaRequest request);
-
-  void abort(SagaRequest request, Exception e);
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaTaskFactory.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaTaskFactory.java
deleted file mode 100644
index 0fd24504..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SagaTaskFactory.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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.core;
-
-import java.lang.invoke.MethodHandles;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class SagaTaskFactory {
-  private final FallbackPolicy fallbackPolicy;
-  private final RetrySagaLog retrySagaLog;
-  private final PersistentStore persistentStore;
-
-  public SagaTaskFactory(int retryDelay, PersistentStore persistentStore) {
-    this.persistentStore = persistentStore;
-
-    fallbackPolicy = new FallbackPolicy(retryDelay);
-    retrySagaLog = new RetrySagaLog(persistentStore, retryDelay);
-  }
-
-  public Map<String, SagaTask> sagaTasks(String sagaId,
-      String requestJson,
-      RecoveryPolicy recoveryPolicy,
-      EventStore sagaLog) {
-
-    SagaLog compositeSagaLog = compositeSagaLog(sagaLog, persistentStore);
-
-    return new HashMap<String, SagaTask>() {{
-      put(SagaTask.SAGA_START_TASK, new SagaStartTask(sagaId, requestJson, compositeSagaLog));
-
-      SagaLog retrySagaLog = compositeSagaLog(sagaLog, SagaTaskFactory.this.retrySagaLog);
-      put(SagaTask.SAGA_REQUEST_TASK,
-          new RequestProcessTask(sagaId, retrySagaLog, new LoggingRecoveryPolicy(recoveryPolicy), fallbackPolicy));
-      put(SagaTask.SAGA_END_TASK, new SagaEndTask(sagaId, retrySagaLog));
-    }};
-  }
-
-  private CompositeSagaLog compositeSagaLog(SagaLog sagaLog, PersistentLog persistentLog) {
-    return new CompositeSagaLog(sagaLog, persistentLog);
-  }
-
-  static class RetrySagaLog implements PersistentLog {
-
-    private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-    private final PersistentStore persistentStore;
-    private final int retryDelay;
-
-    RetrySagaLog(PersistentStore persistentStore, int retryDelay) {
-      this.persistentStore = persistentStore;
-      this.retryDelay = retryDelay;
-    }
-
-    @Override
-    public void offer(SagaEvent sagaEvent) {
-      boolean success = false;
-      do {
-        try {
-          persistentStore.offer(sagaEvent);
-          success = true;
-          log.info("Persisted saga event {} successfully", sagaEvent);
-        } catch (Exception e) {
-          log.error("Failed to persist saga event {}", sagaEvent, e);
-          sleep(retryDelay);
-        }
-      } while (!success && !isInterrupted());
-    }
-
-    private boolean isInterrupted() {
-      return Thread.currentThread().isInterrupted();
-    }
-
-    private void sleep(int delay) {
-      try {
-        Thread.sleep(delay);
-      } catch (InterruptedException e) {
-        Thread.currentThread().interrupt();
-      }
-    }
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SuccessfulSagaResponse.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/SuccessfulSagaResponse.java
deleted file mode 100644
index d69bdcd0..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/SuccessfulSagaResponse.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.core;
-
-public class SuccessfulSagaResponse implements SagaResponse {
-  private final String body;
-
-  public SuccessfulSagaResponse(String body) {
-    this.body = body;
-  }
-
-  @Override
-  public boolean succeeded() {
-    return true;
-  }
-
-  @Override
-  public String body() {
-    return body;
-  }
-
-  @Override
-  public String toString() {
-    return "SuccessfulSagaResponse{" +
-        "body='" + body + '\'' +
-        '}';
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/TaskConsumer.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/TaskConsumer.java
deleted file mode 100644
index 5ae74946..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/TaskConsumer.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.core;
-
-import java.util.Collection;
-
-import org.apache.servicecomb.saga.core.dag.Node;
-
-interface TaskConsumer {
-
-  void consume(Collection<Node<SagaRequest>> nodes);
-
-  boolean replay(Collection<Node<SagaRequest>> nodes);
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/TaskRunner.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/TaskRunner.java
deleted file mode 100644
index c0780018..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/TaskRunner.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.core;
-
-import org.apache.servicecomb.saga.core.dag.Node;
-import org.apache.servicecomb.saga.core.dag.Traveller;
-
-import java.util.Collection;
-
-import kamon.annotation.EnableKamon;
-import kamon.annotation.Segment;
-
-@EnableKamon
-class TaskRunner implements SagaState {
-
-  private final Traveller<SagaRequest> traveller;
-  private final TaskConsumer taskConsumer;
-
-  TaskRunner(Traveller<SagaRequest> traveller, TaskConsumer taskConsumer) {
-    this.traveller = traveller;
-    this.taskConsumer = taskConsumer;
-  }
-
-  @Override
-  public boolean hasNext() {
-    return traveller.hasNext();
-  }
-
-  @Segment(name = "runTask", category = "application", library = "kamon")
-  @Override
-  public void run() {
-    Collection<Node<SagaRequest>> nodes = traveller.nodes();
-
-    // finish pending tasks from saga log at startup
-    if (!nodes.isEmpty()) {
-      taskConsumer.consume(nodes);
-      nodes.clear();
-    }
-
-    while (traveller.hasNext()) {
-      traveller.next();
-      taskConsumer.consume(nodes);
-      nodes.clear();
-    }
-  }
-
-  @Override
-  public void replay() {
-    boolean played = false;
-    Collection<Node<SagaRequest>> nodes = traveller.nodes();
-
-    while (traveller.hasNext() && !played) {
-      traveller.next();
-      played = taskConsumer.replay(nodes);
-    }
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/ToJsonFormat.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/ToJsonFormat.java
deleted file mode 100644
index cd6c4495..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/ToJsonFormat.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.core;
-
-public interface ToJsonFormat {
-
-  String toJson(SagaRequest request);
-
-  String toJson(SagaRequest request, SagaResponse response);
-
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/Transaction.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/Transaction.java
deleted file mode 100644
index fafb8458..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/Transaction.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.core;
-
-public interface Transaction extends Operation {
-
-  Transaction SAGA_START_TRANSACTION = new Transaction() {
-  };
-
-  Transaction SAGA_END_TRANSACTION = new Transaction() {
-  };
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionAbortedEvent.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionAbortedEvent.java
deleted file mode 100644
index b117c94b..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionAbortedEvent.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.core;
-
-public class TransactionAbortedEvent extends SagaEvent {
-
-  private final SagaResponse response;
-
-  public TransactionAbortedEvent(String sagaId, SagaRequest payload, Exception exception) {
-    super(sagaId, payload);
-    this.response = new FailedSagaResponse(exception);
-  }
-
-  public TransactionAbortedEvent(String sagaId, SagaRequest payload, SagaResponse response) {
-    super(sagaId, payload);
-    this.response = response;
-  }
-
-  @Override
-  public void gatherTo(EventContext sagaContext) {
-    // remove from completed operations in order not to compensate it
-    sagaContext.abortTransaction(payload(), response);
-  }
-
-  @Override
-  public String json(ToJsonFormat toJsonFormat) {
-    return toJsonFormat.toJson(payload(), response);
-  }
-
-  @Override
-  public String toString() {
-    return "TransactionAbortedEvent{id="
-        + payload().id()
-        + ", operation="
-        + payload().compensation()
-        + "}";
-  }
-
-  public SagaResponse response() {
-    return response;
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionCompensatedEvent.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionCompensatedEvent.java
deleted file mode 100644
index d6ab2984..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionCompensatedEvent.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.core;
-
-public class TransactionCompensatedEvent extends SagaEvent {
-
-  private final SagaResponse response;
-
-  public TransactionCompensatedEvent(String sagaId, SagaRequest request) {
-    this(sagaId, request, SagaResponse.EMPTY_RESPONSE);
-  }
-
-  public TransactionCompensatedEvent(String sagaId, SagaRequest request, SagaResponse response) {
-    super(sagaId, request);
-    this.response = response;
-  }
-
-  @Override
-  public void gatherTo(EventContext sagaContext) {
-    sagaContext.compensateTransaction(payload(), response);
-  }
-
-  @Override
-  public String json(ToJsonFormat toJsonFormat) {
-    return toJsonFormat.toJson(payload(), response);
-  }
-
-  @Override
-  public String toString() {
-    return "TransactionCompensatedEvent{id="
-        + payload().id()
-        + ", sagaId=" + sagaId
-        + ", operation="
-        + payload().compensation()
-        + "}";
-  }
-
-  public SagaResponse response() {
-    return response;
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionEndedEvent.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionEndedEvent.java
deleted file mode 100644
index 603c542a..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionEndedEvent.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.core;
-
-public class TransactionEndedEvent extends SagaEvent {
-
-  private final SagaResponse response;
-
-  public TransactionEndedEvent(String sagaId, SagaRequest request) {
-    this(sagaId, request, SagaResponse.EMPTY_RESPONSE);
-  }
-
-  public TransactionEndedEvent(String sagaId, SagaRequest request, SagaResponse response) {
-    super(sagaId, request);
-    this.response = response;
-  }
-
-  @Override
-  public void gatherTo(EventContext sagaContext) {
-    sagaContext.endTransaction(payload(), response);
-  }
-
-  @Override
-  public String toString() {
-    return "TransactionEndedEvent{id="
-        + payload().id()
-        + ", sagaId=" + sagaId
-        + ", operation="
-        + payload().transaction()
-        + "}";
-  }
-  
-  @Override
-  public String json(ToJsonFormat toJsonFormat) {
-    return toJsonFormat.toJson(payload(), response);
-  }
-
-  public SagaResponse response() {
-    return response;
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionFailedException.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionFailedException.java
deleted file mode 100644
index b55e01a3..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionFailedException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.core;
-
-public class TransactionFailedException extends RuntimeException {
-
-  public TransactionFailedException(Throwable throwable) {
-    super(throwable);
-  }
-
-  public TransactionFailedException(String cause) {
-    super(cause);
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionStartedEvent.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionStartedEvent.java
deleted file mode 100644
index cc355893..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionStartedEvent.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.core;
-
-public class TransactionStartedEvent extends SagaEvent {
-
-  public TransactionStartedEvent(String sagaId, SagaRequest transaction) {
-    super(sagaId, transaction);
-  }
-
-  @Override
-  public void gatherTo(EventContext sagaContext) {
-    sagaContext.beginTransaction(payload());
-  }
-
-  @Override
-  public String toString() {
-    return "TransactionStartedEvent{id="
-        + payload().id()
-        + ", sagaId=" + sagaId
-        + ", operation="
-        + payload().transaction()
-        + "}";
-  }
-  
-  @Override
-  public String json(ToJsonFormat toJsonFormat) {
-    return toJsonFormat.toJson(payload());
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionTaskConsumer.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionTaskConsumer.java
deleted file mode 100644
index af2dc742..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransactionTaskConsumer.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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.core;
-
-import org.apache.servicecomb.saga.core.dag.Node;
-import java.lang.invoke.MethodHandles;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CompletionService;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-
-import kamon.annotation.EnableKamon;
-import kamon.annotation.Segment;
-import kamon.annotation.Trace;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@EnableKamon
-class TransactionTaskConsumer implements TaskConsumer {
-
-  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-  private final Map<String, SagaTask> tasks;
-  private final SagaContext sagaContext;
-  private final CompletionService<Operation> executorService;
-
-  TransactionTaskConsumer(
-      Map<String, SagaTask> tasks,
-      SagaContext sagaContext,
-      CompletionService<Operation> executorService) {
-
-    this.tasks = tasks;
-    this.sagaContext = sagaContext;
-    this.executorService = executorService;
-  }
-
-  @Segment(name = "consumeTask", category = "application", library = "kamon")
-  @Override
-  public void consume(Collection<Node<SagaRequest>> nodes) {
-    List<Future<Operation>> futures = new ArrayList<>(nodes.size());
-    for (Node<SagaRequest> node : nodes) {
-      SagaRequest request = node.value();
-      if (sagaContext.isChosenChild(request)) {
-        futures.add(futureOf(request));
-      }
-    }
-
-    for (int i = 0; i < futures.size(); i++) {
-      try {
-        executorService.take().get();
-      } catch (ExecutionException e) {
-        if (e.getCause() instanceof SagaStartFailedException) {
-          throw ((SagaStartFailedException) e.getCause());
-        }
-        throw new TransactionFailedException(e.getCause());
-      } catch (InterruptedException e) {
-        // TODO: 7/29/2017 what shall we do when system is shutting down?
-        throw new TransactionFailedException(e);
-      }
-    }
-  }
-
-  @Override
-  public boolean replay(Collection<Node<SagaRequest>> nodes) {
-    for (Iterator<Node<SagaRequest>> iterator = nodes.iterator(); iterator.hasNext(); ) {
-      SagaRequest request = iterator.next().value();
-      if (sagaContext.isTransactionCompleted(request)) {
-        log.info("Skipped completed transaction id={} operation={} while replay", request.id(), request.transaction());
-        iterator.remove();
-      }
-    }
-    return !nodes.isEmpty();
-  }
-
-  @Segment(name = "submitCallable", category = "application", library = "kamon")
-  private Future<Operation> futureOf(SagaRequest request) {
-    return executorService.submit(new OperationCallable(tasks, request, sagaContext.responseOf(request.parents())));
-  }
-
-  @EnableKamon
-  private static class OperationCallable implements Callable<Operation> {
-
-    private final SagaRequest request;
-    private final Map<String, SagaTask> tasks;
-    private final SagaResponse parentResponse;
-
-    private OperationCallable(
-        Map<String, SagaTask> tasks,
-        SagaRequest request,
-        SagaResponse parentResponse) {
-      this.request = request;
-      this.tasks = tasks;
-      this.parentResponse = parentResponse;
-    }
-
-    @Trace("runTransactionCallable")
-    @Override
-    public Operation call() throws Exception {
-      tasks.get(request.task()).commit(request, parentResponse);
-      return request.transaction();
-    }
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/Transport.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/Transport.java
deleted file mode 100644
index 5679e0a4..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/Transport.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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.core;
-
-public interface Transport {
-
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransportFailedException.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransportFailedException.java
deleted file mode 100644
index e01a9d58..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/TransportFailedException.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.core;
-
-public class TransportFailedException extends RuntimeException {
-  public TransportFailedException(String cause) {
-    super(cause);
-  }
-
-  public TransportFailedException(String cause, Throwable e) {
-    super(cause, e);
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/ActorBasedSaga.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/ActorBasedSaga.java
deleted file mode 100644
index bf60f988..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/ActorBasedSaga.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.core.actors;
-
-import java.util.concurrent.CompletableFuture;
-
-import org.apache.servicecomb.saga.core.EventContext;
-import org.apache.servicecomb.saga.core.EventStore;
-import org.apache.servicecomb.saga.core.NoOpSagaRequest;
-import org.apache.servicecomb.saga.core.Saga;
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.apache.servicecomb.saga.core.actors.messages.TransactMessage;
-import org.apache.servicecomb.saga.core.SagaEvent;
-
-import akka.actor.ActorRef;
-
-public class ActorBasedSaga implements Saga {
-  private final ActorRef root;
-  private final ActorRef completionCallback;
-  private final CompletableFuture<SagaResponse> future;
-  private final EventStore sagaLog;
-  private final EventContext sagaContext;
-
-  ActorBasedSaga(ActorRef root, ActorRef completionCallback, CompletableFuture<SagaResponse> future, EventStore sagaLog,
-      EventContext sagaContext) {
-    this.root = root;
-    this.completionCallback = completionCallback;
-    this.future = future;
-    this.sagaLog = sagaLog;
-    this.sagaContext = sagaContext;
-  }
-
-  @Override
-  public SagaResponse run() {
-    root.tell(new TransactMessage(NoOpSagaRequest.SAGA_START_REQUEST, SagaResponse.EMPTY_RESPONSE), completionCallback);
-
-    return future.join();
-  }
-
-  @Override
-  public void play() {
-    gatherEvents(sagaLog);
-  }
-
-  private void gatherEvents(Iterable<SagaEvent> events) {
-    for (SagaEvent event : events) {
-      event.gatherTo(sagaContext);
-    }
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/ActorBasedSagaFactory.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/ActorBasedSagaFactory.java
deleted file mode 100644
index 8ce22fa6..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/ActorBasedSagaFactory.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.core.actors;
-
-import static akka.actor.ActorRef.noSender;
-
-import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-
-import org.apache.servicecomb.saga.core.EventStore;
-import org.apache.servicecomb.saga.core.NoOpSagaRequest;
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.apache.servicecomb.saga.core.application.SagaFactory;
-import org.apache.servicecomb.saga.core.PersistentStore;
-import org.apache.servicecomb.saga.core.SagaDefinition;
-import org.apache.servicecomb.saga.core.SagaTaskFactory;
-import org.apache.servicecomb.saga.core.application.interpreter.FromJsonFormat;
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import scala.concurrent.Await;
-import scala.concurrent.duration.Duration;
-
-public class ActorBasedSagaFactory implements SagaFactory {
-  private final ActorSystem actorSystem = ActorSystem.create("saga");
-  private final RequestActorBuilder actorBuilder;
-  private final SagaTaskFactory sagaTaskFactory;
-
-  public ActorBasedSagaFactory(int retryDelay,
-      PersistentStore persistentStore,
-      FromJsonFormat<Set<String>> childrenExtractor) {
-
-    this.sagaTaskFactory = new SagaTaskFactory(retryDelay, persistentStore);
-    this.actorBuilder = new RequestActorBuilder(actorSystem, childrenExtractor);
-  }
-
-  @Override
-  public ActorBasedSaga createSaga(String requestJson, String sagaId, EventStore sagaLog, SagaDefinition definition) {
-
-    CompletableFuture<SagaResponse> future = new CompletableFuture<>();
-    ActorRef completionCallback = actorSystem.actorOf(CompletionCallbackActor.props(future));
-    RequestActorContext context = actorBuilder.build(
-        definition.requests(),
-        sagaTaskFactory.sagaTasks(sagaId,
-            requestJson,
-            definition.policy(),
-            sagaLog
-        ),
-        completionCallback);
-
-    completionCallback.tell(context, noSender());
-    return new ActorBasedSaga(
-        context.actorOf(NoOpSagaRequest.SAGA_START_REQUEST.id()),
-        completionCallback,
-        future,
-        sagaLog,
-        new EventContextImpl(context));
-  }
-
-  @Override
-  public boolean isTerminated() {
-    return actorSystem.whenTerminated().isCompleted();
-  }
-
-  @Override
-  public void terminate() throws Exception {
-    Await.result(actorSystem.terminate(), Duration.Inf());
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/CompletionCallbackActor.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/CompletionCallbackActor.java
deleted file mode 100644
index 7cee4d30..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/CompletionCallbackActor.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.core.actors;
-
-import java.util.concurrent.CompletableFuture;
-
-import org.apache.servicecomb.saga.core.NoOpSagaRequest;
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.apache.servicecomb.saga.core.actors.messages.AbortMessage;
-import org.apache.servicecomb.saga.core.actors.messages.CompensateMessage;
-import org.apache.servicecomb.saga.core.actors.messages.FailMessage;
-import org.apache.servicecomb.saga.core.actors.messages.TransactMessage;
-import akka.actor.AbstractLoggingActor;
-import akka.actor.Props;
-
-class CompletionCallbackActor extends AbstractLoggingActor {
-  private final CompletableFuture<SagaResponse> future;
-
-  private CompletionCallbackActor(CompletableFuture<SagaResponse> future) {
-    this.future = future;
-  }
-
-  static Props props(CompletableFuture<SagaResponse> future) {
-    return Props.create(CompletionCallbackActor.class, () -> new CompletionCallbackActor(future));
-  }
-
-  @Override
-  public Receive createReceive() {
-    return receiveBuilder()
-        .match(RequestActorContext.class, this::ready)
-        .build();
-  }
-
-  private void ready(RequestActorContext context) {
-    getContext().become(receiveBuilder()
-        .match(CompensateMessage.class, message -> end(context, message.response()))
-        .match(TransactMessage.class, message -> end(context, message.response()))
-        .match(AbortMessage.class, message -> onAbort(context, message))
-        .match(FailMessage.class, message -> end(context, message.response()))
-        .build());
-  }
-
-  private void onAbort(RequestActorContext context, AbortMessage message) {
-    log().info("saga actor: received abort message of {}", message.response());
-    context.actorOf(NoOpSagaRequest.SAGA_END_REQUEST.id()).tell(new CompensateMessage(message.response()), self());
-  }
-
-  private void end(RequestActorContext context, SagaResponse response) {
-    log().info("saga actor: received response {}", response);
-    future.complete(response);
-    context.forAll(actor -> getContext().stop(actor));
-    getContext().stop(self());
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/EventContextImpl.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/EventContextImpl.java
deleted file mode 100644
index 21a2928a..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/EventContextImpl.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.core.actors;
-
-import static akka.actor.ActorRef.noSender;
-
-import org.apache.servicecomb.saga.core.EventContext;
-import org.apache.servicecomb.saga.core.SagaRequest;
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.apache.servicecomb.saga.core.actors.messages.AbortRecoveryMessage;
-import org.apache.servicecomb.saga.core.actors.messages.CompensationRecoveryMessage;
-import org.apache.servicecomb.saga.core.actors.messages.TransactionRecoveryMessage;
-import org.apache.servicecomb.saga.core.actors.messages.Message;
-
-public class EventContextImpl implements EventContext {
-  private final RequestActorContext context;
-
-  EventContextImpl(RequestActorContext context) {
-    this.context = context;
-  }
-
-  @Override
-  public void beginTransaction(SagaRequest request) {
-
-  }
-
-  @Override
-  public void endTransaction(SagaRequest request, SagaResponse response) {
-    sendMessage(request, new TransactionRecoveryMessage(response));
-  }
-
-  @Override
-  public void abortTransaction(SagaRequest request, SagaResponse response) {
-    sendMessage(request, new AbortRecoveryMessage(response));
-  }
-
-  @Override
-  public void compensateTransaction(SagaRequest request, SagaResponse response) {
-    sendMessage(request, new CompensationRecoveryMessage());
-  }
-
-  private void sendMessage(SagaRequest request, Message message) {
-    context.actorOf(request.id()).tell(message, noSender());
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/RequestActor.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/RequestActor.java
deleted file mode 100644
index 055174e2..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/RequestActor.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * 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.core.actors;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
-
-import org.apache.servicecomb.saga.core.CompositeSagaResponse;
-import org.apache.servicecomb.saga.core.SagaRequest;
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.apache.servicecomb.saga.core.SagaStartFailedException;
-import org.apache.servicecomb.saga.core.SagaTask;
-import org.apache.servicecomb.saga.core.TransactionFailedException;
-import org.apache.servicecomb.saga.core.actors.messages.AbortMessage;
-import org.apache.servicecomb.saga.core.actors.messages.AbortRecoveryMessage;
-import org.apache.servicecomb.saga.core.actors.messages.CompensationRecoveryMessage;
-import org.apache.servicecomb.saga.core.actors.messages.FailMessage;
-import org.apache.servicecomb.saga.core.actors.messages.Message;
-import org.apache.servicecomb.saga.core.actors.messages.TransactMessage;
-import org.apache.servicecomb.saga.core.actors.messages.TransactionRecoveryMessage;
-import org.apache.servicecomb.saga.core.actors.messages.CompensateMessage;
-
-import akka.actor.AbstractLoggingActor;
-import akka.actor.ActorRef;
-import akka.actor.Props;
-import akka.japi.pf.ReceiveBuilder;
-
-public class RequestActor extends AbstractLoggingActor {
-  private final RequestActorContext context;
-  private final SagaTask task;
-  private final SagaRequest request;
-
-  private final List<SagaResponse> parentResponses;
-  private final List<ActorRef> compensatedChildren;
-
-  private final Receive transacted;
-  private final Receive aborted;
-
-  static Props props(
-      RequestActorContext context,
-      SagaTask task,
-      SagaRequest request) {
-    return Props.create(RequestActor.class, () -> new RequestActor(context, task, request));
-  }
-
-  private RequestActor(
-      RequestActorContext context,
-      SagaTask task,
-      SagaRequest request) {
-    this.context = context;
-    this.task = task;
-    this.request = request;
-    this.parentResponses = new ArrayList<>(request.parents().length);
-    this.compensatedChildren = new LinkedList<>();
-
-    this.aborted = onReceive(ignored -> {
-    }).build();
-
-    this.transacted = onReceive(task::compensate)
-        .match(CompensationRecoveryMessage.class, message -> getContext().become(aborted))
-        .build();
-  }
-
-  @Override
-  public Receive createReceive() {
-    return receiveBuilder()
-        .match(TransactMessage.class,
-            message -> onTransaction(message, () -> task.commit(request, responseOf(parentResponses))))
-        .match(TransactionRecoveryMessage.class, this::onTransactRecovery)
-        .match(AbortRecoveryMessage.class, this::onAbortRecovery)
-        .match(AbortMessage.class, this::onAbort)
-        .build();
-  }
-
-  private void onAbort(AbortMessage message) {
-    log().debug("{}: received abort message of {}", request.id(), message.response());
-    sendToChildrenButSender(message);
-    sendToParentsButSender(message);
-
-    getContext().become(aborted);
-  }
-
-  private void sendToParentsButSender(AbortMessage message) {
-    context.parentsOf(request)
-        .stream()
-        .filter(this::isNotSender)
-        .forEach(actor -> actor.tell(message, self()));
-  }
-
-  private void sendToChildrenButSender(AbortMessage message) {
-    context.childrenOf(request)
-        .stream()
-        .filter(this::isNotSender)
-        .forEach(actor -> actor.tell(message, self()));
-  }
-
-  private boolean isNotSender(ActorRef actor) {
-    return !actor.equals(sender());
-  }
-
-  private void onTransactRecovery(TransactionRecoveryMessage message) {
-    getContext().become(receiveBuilder()
-        .match(TransactMessage.class, m -> onTransaction(m, message::response))
-        .match(CompensationRecoveryMessage.class, m -> getContext().become(aborted))
-        .build()
-    );
-  }
-
-  private void onAbortRecovery(AbortRecoveryMessage message) {
-    getContext().become(
-        receiveBuilder()
-            .match(TransactMessage.class, m -> onAbort(new AbortMessage(message.response())))
-            .build());
-  }
-
-  private void onTransaction(TransactMessage message, Supplier<SagaResponse> responseSupplier) {
-    log().debug("{}: received transaction message of {}", request.id(), message.request());
-    if (context.parentsOf(request).contains(sender())) {
-      parentResponses.add(message.response());
-    }
-
-    if (parentResponses.size() == context.parentsOf(request).size()) {
-      transact(responseSupplier);
-    }
-  }
-
-  private void transact(Supplier<SagaResponse> responseSupplier) {
-    try {
-      if (isChosenChild(parentResponses)) {
-        SagaResponse sagaResponse = responseSupplier.get();
-        sendToChildren(new TransactMessage(request, sagaResponse));
-        getContext().become(transacted);
-      } else {
-        sendToChildren(new TransactMessage(request, SagaResponse.NONE_RESPONSE));
-        getContext().become(aborted);
-      }
-    } catch (SagaStartFailedException e) {
-      sendToParents(new FailMessage(e));
-    } catch (Exception e) {
-      log().error("Failed to run operation {} with error {}", request.transaction(), e);
-
-      Message abortMessage = new AbortMessage(new TransactionFailedException(e));
-      sendToParents(abortMessage);
-      sendToChildren(abortMessage);
-      getContext().become(aborted);
-    }
-  }
-
-  private void sendToParents(Message message) {
-    context.parentsOf(request).forEach(actor -> actor.tell(message, self()));
-  }
-
-  private void sendToChildren(Message message) {
-    context.childrenOf(request).forEach(actor -> actor.tell(message, self()));
-  }
-
-  private boolean isChosenChild(List<SagaResponse> parentResponses) {
-    return request.parents().length == 0 || parentResponses.isEmpty() || parentResponses.stream()
-            .map(context::chosenChildren)
-            .anyMatch(chosenChildren -> chosenChildren.isEmpty() || chosenChildren.contains(request.id()));
-  }
-
-  private SagaResponse responseOf(List<SagaResponse> responseContexts) {
-    if (responseContexts.isEmpty()) {
-      return SagaResponse.EMPTY_RESPONSE;
-    }
-
-    if (responseContexts.size() == 1) {
-      return responseContexts.get(0);
-    }
-    return new CompositeSagaResponse(responseContexts);
-  }
-
-  private ReceiveBuilder onReceive(Consumer<SagaRequest> requestConsumer) {
-    return receiveBuilder()
-        .match(CompensateMessage.class, message -> onCompensate(message, requestConsumer));
-  }
-
-  private void onCompensate(CompensateMessage message, Consumer<SagaRequest> requestConsumer) {
-    log().debug("{}: received compensation message from {}", request.id(), sender());
-    compensatedChildren.add(sender());
-
-    if (compensatedChildren.size() == context.childrenOf(request).size()) {
-      requestConsumer.accept(request);
-      sendToParents(message);
-    }
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/RequestActorBuilder.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/RequestActorBuilder.java
deleted file mode 100644
index 5004b4ec..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/RequestActorBuilder.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * 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.core.actors;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.servicecomb.saga.core.NoOpSagaRequest;
-import org.apache.servicecomb.saga.core.SagaRequest;
-import org.apache.servicecomb.saga.core.SagaTask;
-import org.apache.servicecomb.saga.core.application.interpreter.FromJsonFormat;
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.actor.Props;
-
-public class RequestActorBuilder {
-  private final ActorSystem actorSystem;
-  private final FromJsonFormat<Set<String>> childrenExtractor;
-
-  RequestActorBuilder(
-      ActorSystem actorSystem,
-      FromJsonFormat<Set<String>> childrenExtractor) {
-
-    this.actorSystem = actorSystem;
-    this.childrenExtractor = childrenExtractor;
-  }
-
-  public RequestActorContext build(SagaRequest[] requests, Map<String, SagaTask> tasks, ActorRef sagaActor) {
-    RequestActorContext context = new RequestActorContext(childrenExtractor);
-
-    ActorRef rootActor = rootActor(context, tasks);
-    ActorRef leafActor = leafActor(context, tasks);
-
-    createRequestActors(requests, tasks, context);
-
-    linkActorsById(rootActor, requests, context);
-    addLeafToChildless(leafActor, requests, context);
-
-    context.addParent(NoOpSagaRequest.SAGA_START_REQUEST.id(), sagaActor);
-    context.addChild(NoOpSagaRequest.SAGA_END_REQUEST.id(), sagaActor);
-    return context;
-  }
-
-  private void linkActorsById(ActorRef rootActor, SagaRequest[] requests, RequestActorContext context) {
-    for (SagaRequest request : requests) {
-      if (isOrphan(request)) {
-        context.addParent(request.id(), rootActor);
-        context.addChild(NoOpSagaRequest.SAGA_START_REQUEST.id(), context.actorOf(request.id()));
-      } else {
-        for (String parent : request.parents()) {
-          context.addParent(request.id(), context.actorOf(parent));
-          context.addChild(parent, context.actorOf(request.id()));
-        }
-      }
-    }
-  }
-
-  private boolean isOrphan(SagaRequest request) {
-    return request.parents().length == 0;
-  }
-
-  private void createRequestActors(SagaRequest[] requests, Map<String, SagaTask> tasks, RequestActorContext context) {
-    for (SagaRequest request : requests) {
-      Props props = RequestActor.props(context, tasks.get(request.task()), request);
-      context.addActor(request.id(), actorSystem.actorOf(props));
-    }
-  }
-
-  private void addLeafToChildless(ActorRef leafActor, SagaRequest[] requests, RequestActorContext context) {
-    for (SagaRequest request : requests) {
-      if (context.childrenOf(request).isEmpty()) {
-        context.addParent(NoOpSagaRequest.SAGA_END_REQUEST.id(), context.actorOf(request.id()));
-        context.addChild(request.id(), leafActor);
-      }
-    }
-  }
-
-  private ActorRef rootActor(RequestActorContext context, Map<String, SagaTask> tasks) {
-    Props root = RequestActor.props(context, tasks.get(
-        NoOpSagaRequest.SAGA_START_REQUEST.task()), NoOpSagaRequest.SAGA_START_REQUEST);
-    ActorRef actor = actorSystem.actorOf(root);
-    context.addActor(NoOpSagaRequest.SAGA_START_REQUEST.id(), actor);
-    return actor;
-  }
-
-  private ActorRef leafActor(RequestActorContext context, Map<String, SagaTask> tasks) {
-    Props leaf = RequestActor.props(context, tasks.get(
-        NoOpSagaRequest.SAGA_END_REQUEST.task()), NoOpSagaRequest.SAGA_END_REQUEST);
-    ActorRef actor = actorSystem.actorOf(leaf);
-    context.addActor(NoOpSagaRequest.SAGA_END_REQUEST.id(), actor);
-    return actor;
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/RequestActorContext.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/RequestActorContext.java
deleted file mode 100644
index 2e3149d4..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/RequestActorContext.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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.core.actors;
-
-import static java.util.Collections.emptyList;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.Consumer;
-
-import org.apache.servicecomb.saga.core.SagaRequest;
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.apache.servicecomb.saga.core.application.interpreter.FromJsonFormat;
-import akka.actor.ActorRef;
-
-class RequestActorContext {
-  private final Map<String, ActorRef> actors;
-  private final Map<String, List<ActorRef>> parents;
-  private final Map<String, List<ActorRef>> children;
-  private final FromJsonFormat<Set<String>> childrenExtractor;
-
-  RequestActorContext(
-      FromJsonFormat<Set<String>> childrenExtractor) {
-    this.actors = new HashMap<>();
-    this.children = new HashMap<>();
-    this.parents = new HashMap<>();
-    this.childrenExtractor = childrenExtractor;
-  }
-
-  void addActor(String id, ActorRef actorRef) {
-    actors.put(id, actorRef);
-  }
-
-  void addChild(String requestId, ActorRef ref) {
-    children.computeIfAbsent(requestId, k -> new ArrayList<>()).add(ref);
-  }
-
-  void addParent(String requestId, ActorRef ref) {
-    parents.computeIfAbsent(requestId, k -> new ArrayList<>()).add(ref);
-  }
-
-  ActorRef actorOf(String id) {
-    return actors.get(id);
-  }
-
-  Collection<ActorRef> parentsOf(SagaRequest request) {
-    return parents.getOrDefault(request.id(), emptyList());
-  }
-
-  Collection<ActorRef> childrenOf(SagaRequest request) {
-    return children.getOrDefault(request.id(), emptyList());
-  }
-
-  void forAll(Consumer<ActorRef> consumer) {
-    actors.values()
-        .stream()
-        .forEach(consumer);
-  }
-
-  Set<String> chosenChildren(SagaResponse response) {
-    return childrenExtractor.fromJson(response.body());
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/AbortMessage.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/AbortMessage.java
deleted file mode 100644
index f23a0790..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/AbortMessage.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.core.actors.messages;
-
-import org.apache.servicecomb.saga.core.FailedSagaResponse;
-import org.apache.servicecomb.saga.core.SagaResponse;
-
-public class AbortMessage implements Message {
-  private final SagaResponse response;
-
-  public AbortMessage(Throwable e) {
-    response = new FailedSagaResponse(e);
-  }
-
-  public AbortMessage(SagaResponse response) {
-    this.response = response;
-  }
-
-  public SagaResponse response() {
-    return response;
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/AbortRecoveryMessage.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/AbortRecoveryMessage.java
deleted file mode 100644
index 951157d2..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/AbortRecoveryMessage.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.core.actors.messages;
-
-import org.apache.servicecomb.saga.core.SagaResponse;
-
-public class AbortRecoveryMessage implements Message {
-
-  private final SagaResponse response;
-
-  public AbortRecoveryMessage(SagaResponse response) {
-    this.response = response;
-  }
-
-  public SagaResponse response() {
-    return response;
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/CompensateMessage.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/CompensateMessage.java
deleted file mode 100644
index 5fd07019..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/CompensateMessage.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.core.actors.messages;
-
-import org.apache.servicecomb.saga.core.SagaResponse;
-
-public class CompensateMessage implements Message {
-  private final SagaResponse response;
-
-  public CompensateMessage(SagaResponse response) {
-    this.response = response;
-  }
-
-  public SagaResponse response() {
-    return response;
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/CompensationRecoveryMessage.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/CompensationRecoveryMessage.java
deleted file mode 100644
index 421a0928..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/CompensationRecoveryMessage.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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.core.actors.messages;
-
-public class CompensationRecoveryMessage implements Message {
-
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/FailMessage.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/FailMessage.java
deleted file mode 100644
index 7a80ecb6..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/FailMessage.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.core.actors.messages;
-
-import org.apache.servicecomb.saga.core.FailedSagaResponse;
-import org.apache.servicecomb.saga.core.SagaResponse;
-
-public class FailMessage implements Message {
-  private final SagaResponse response;
-
-  public FailMessage(Throwable e) {
-    response = new FailedSagaResponse(e);
-  }
-
-  public SagaResponse response() {
-    return response;
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/Message.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/Message.java
deleted file mode 100644
index 3ed81876..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/Message.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * 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.core.actors.messages;
-
-public interface Message {
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/TransactMessage.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/TransactMessage.java
deleted file mode 100644
index e4c57a28..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/TransactMessage.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.core.actors.messages;
-
-import org.apache.servicecomb.saga.core.SagaRequest;
-import org.apache.servicecomb.saga.core.SagaResponse;
-
-public class TransactMessage implements Message {
-  private final SagaRequest request;
-  private final SagaResponse response;
-
-  public TransactMessage(SagaRequest request, SagaResponse response) {
-    this.request = request;
-    this.response = response;
-  }
-
-  public SagaRequest request() {
-    return request;
-  }
-
-  public SagaResponse response() {
-    return response;
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/TransactionRecoveryMessage.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/TransactionRecoveryMessage.java
deleted file mode 100644
index 26ba05b8..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/actors/messages/TransactionRecoveryMessage.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.core.actors.messages;
-
-import org.apache.servicecomb.saga.core.SagaResponse;
-
-public class TransactionRecoveryMessage implements Message {
-  private final SagaResponse response;
-
-  public TransactionRecoveryMessage(SagaResponse response) {
-    this.response = response;
-  }
-
-  public SagaResponse response() {
-    return response;
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/application/SagaExecutionComponent.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/application/SagaExecutionComponent.java
deleted file mode 100644
index 7a600d7e..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/application/SagaExecutionComponent.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.core.application;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.UUID;
-
-import org.apache.servicecomb.saga.core.EventEnvelope;
-import org.apache.servicecomb.saga.core.EventStore;
-import org.apache.servicecomb.saga.core.Saga;
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.apache.servicecomb.saga.core.ToJsonFormat;
-import org.apache.servicecomb.saga.core.PersistentStore;
-import org.apache.servicecomb.saga.core.SagaDefinition;
-import org.apache.servicecomb.saga.core.SagaEvent;
-import org.apache.servicecomb.saga.core.application.interpreter.FromJsonFormat;
-import org.apache.servicecomb.saga.infrastructure.EmbeddedEventStore;
-import kamon.annotation.EnableKamon;
-import kamon.annotation.Segment;
-
-@EnableKamon
-public class SagaExecutionComponent {
-
-  private final PersistentStore persistentStore;
-  private final FromJsonFormat<SagaDefinition> fromJsonFormat;
-  private final ToJsonFormat toJsonFormat;
-  private final SagaFactory sagaFactory;
-
-  public SagaExecutionComponent(
-      PersistentStore persistentStore,
-      FromJsonFormat<SagaDefinition> fromJsonFormat,
-      ToJsonFormat toJsonFormat,
-      SagaFactory sagaFactory) {
-    this.persistentStore = persistentStore;
-    this.fromJsonFormat = fromJsonFormat;
-    this.toJsonFormat = toJsonFormat;
-    this.sagaFactory = sagaFactory;
-  }
-
-  @Segment(name = "runSagaExecutionComponent", category = "application", library = "kamon")
-  public SagaResponse run(String requestJson) {
-    String sagaId = UUID.randomUUID().toString();
-    EventStore sagaLog = new EmbeddedEventStore();
-    SagaDefinition definition = fromJsonFormat.fromJson(requestJson);
-    Saga saga = sagaFactory.createSaga(requestJson, sagaId, sagaLog, definition);
-    return saga.run();
-  }
-
-  public void reanimate() {
-    Map<String, List<EventEnvelope>> pendingSagaEvents = persistentStore.findPendingSagaEvents();
-
-    for (Entry<String, List<EventEnvelope>> entry : pendingSagaEvents.entrySet()) {
-      EventStore eventStore = new EmbeddedEventStore();
-      eventStore.populate(entry.getValue());
-      SagaEvent event = entry.getValue().iterator().next().event;
-
-      String requestJson = event.json(toJsonFormat);
-      SagaDefinition definition = fromJsonFormat.fromJson(requestJson);
-
-      Saga saga = sagaFactory.createSaga(requestJson, event.sagaId, eventStore, definition);
-
-      saga.play();
-      saga.run();
-    }
-  }
-
-  public void terminate() throws Exception {
-    sagaFactory.terminate();
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/application/SagaFactory.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/application/SagaFactory.java
deleted file mode 100644
index b60b5e74..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/application/SagaFactory.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.core.application;
-
-import org.apache.servicecomb.saga.core.EventStore;
-import org.apache.servicecomb.saga.core.Saga;
-import org.apache.servicecomb.saga.core.SagaDefinition;
-
-public interface SagaFactory {
-  Saga createSaga(String requestJson, String sagaId, EventStore sagaLog, SagaDefinition definition);
-
-  boolean isTerminated();
-
-  void terminate() throws Exception;
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/application/interpreter/FromJsonFormat.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/application/interpreter/FromJsonFormat.java
deleted file mode 100644
index ccfb4082..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/application/interpreter/FromJsonFormat.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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.core.application.interpreter;
-
-public interface FromJsonFormat<T> {
-
-  T fromJson(String requestJson);
-
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/application/interpreter/RestRequestChecker.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/application/interpreter/RestRequestChecker.java
deleted file mode 100644
index 7a65e48c..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/application/interpreter/RestRequestChecker.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.core.application.interpreter;
-
-import static java.util.Arrays.asList;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-public class RestRequestChecker {
-
-  private static final Set<String> validMethods = new HashSet<>(asList(
-      "GET",
-      "POST",
-      "PUT",
-      "DELETE"
-  ));
-
-  private RestRequestChecker() {
-  }
-
-  public static void checkParameters(String method, Map<String, Map<String, String>> params) {
-    if (method == null || !validMethods.contains(method.toUpperCase())) {
-      throw new IllegalArgumentException("Unsupported method " + method);
-    }
-
-    if (isDeleteOrGet(method) && hasBody(params)) {
-      throw new IllegalArgumentException("GET & DELETE request cannot enclose a body");
-    }
-  }
-
-  private static boolean isDeleteOrGet(String method) {
-    return "GET".equalsIgnoreCase(method) || "DELETE".equalsIgnoreCase(method);
-  }
-
-  private static boolean hasBody(Map<String, Map<String, String>> params) {
-    return params != null && (params.containsKey("form") || params.containsKey("json"));
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/ByLevelTraveller.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/ByLevelTraveller.java
deleted file mode 100644
index 22bc8748..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/ByLevelTraveller.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.core.dag;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Queue;
-import java.util.Set;
-import kamon.annotation.EnableKamon;
-import kamon.annotation.Segment;
-
-@EnableKamon
-public class ByLevelTraveller<T> implements Traveller<T> {
-
-  private final Collection<Node<T>> nodes;
-  private final Collection<Node<T>> nodesBuffer;
-
-  private final Queue<Node<T>> nodesWithoutParent = new LinkedList<>();
-  private final Map<Long, Set<Node<T>>> nodeParents = new HashMap<>();
-  private final TraversalDirection<T> traversalDirection;
-
-
-  public ByLevelTraveller(SingleLeafDirectedAcyclicGraph<T> dag, TraversalDirection<T> traversalDirection) {
-    this.nodes = new LinkedHashSet<>();
-    this.nodesBuffer = new LinkedList<>();
-    this.traversalDirection = traversalDirection;
-
-    nodesWithoutParent.offer(traversalDirection.root(dag));
-  }
-
-  @Segment(name = "travelNext", category = "application", library = "kamon")
-  @Override
-  public void next() {
-    nodes.addAll(nodesBuffer);
-    nodesBuffer.clear();
-    boolean buffered = false;
-
-    while (!nodesWithoutParent.isEmpty() && !buffered) {
-      Node<T> node = nodesWithoutParent.poll();
-      nodes.add(node);
-
-      for (Node<T> child : traversalDirection.children(node)) {
-        nodeParents.computeIfAbsent(child.id(), id -> new HashSet<>(traversalDirection.parents(child)));
-        nodeParents.get(child.id()).remove(node);
-
-        if (nodeParents.get(child.id()).isEmpty()) {
-          nodesWithoutParent.offer(child);
-          nodesBuffer.add(child);
-          buffered = true;
-        }
-      }
-    }
-  }
-
-  @Override
-  public boolean hasNext() {
-    return !nodesWithoutParent.isEmpty();
-  }
-
-  @Override
-  public Collection<Node<T>> nodes() {
-    return nodes;
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/FromLeafTraversalDirection.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/FromLeafTraversalDirection.java
deleted file mode 100644
index d97c40fc..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/FromLeafTraversalDirection.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.core.dag;
-
-import java.util.Set;
-
-public class FromLeafTraversalDirection<T> implements TraversalDirection<T> {
-
-  @Override
-  public Node<T> root(SingleLeafDirectedAcyclicGraph<T> dag) {
-    return dag.leaf();
-  }
-
-  @Override
-  public Set<Node<T>> parents(Node<T> node) {
-    return node.children();
-  }
-
-  @Override
-  public Set<Node<T>> children(Node<T> node) {
-    return node.parents();
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/FromRootTraversalDirection.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/FromRootTraversalDirection.java
deleted file mode 100644
index 8c664ac5..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/FromRootTraversalDirection.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.core.dag;
-
-import java.util.Set;
-
-public class FromRootTraversalDirection<T> implements TraversalDirection<T> {
-
-  @Override
-  public Node<T> root(SingleLeafDirectedAcyclicGraph<T> dag) {
-    return dag.root();
-  }
-
-  @Override
-  public Set<Node<T>> parents(Node<T> node) {
-    return node.parents();
-  }
-
-  @Override
-  public Set<Node<T>> children(Node<T> node) {
-    return node.children();
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/GraphBasedSagaFactory.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/GraphBasedSagaFactory.java
deleted file mode 100644
index 2048383f..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/GraphBasedSagaFactory.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.core.dag;
-
-import java.util.Set;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.servicecomb.saga.core.EventStore;
-import org.apache.servicecomb.saga.core.GraphBasedSaga;
-import org.apache.servicecomb.saga.core.Saga;
-import org.apache.servicecomb.saga.core.SagaContext;
-import org.apache.servicecomb.saga.core.SagaContextImpl;
-import org.apache.servicecomb.saga.core.application.SagaFactory;
-import org.apache.servicecomb.saga.infrastructure.ContextAwareEventStore;
-import org.apache.servicecomb.saga.core.PersistentStore;
-import org.apache.servicecomb.saga.core.SagaDefinition;
-import org.apache.servicecomb.saga.core.SagaTaskFactory;
-import org.apache.servicecomb.saga.core.application.interpreter.FromJsonFormat;
-
-public class GraphBasedSagaFactory implements SagaFactory {
-  private final AtomicBoolean isRunning = new AtomicBoolean(true);
-  private final FromJsonFormat<Set<String>> childrenExtractor;
-  private final Executor executorService;
-  private final GraphBuilder graphBuilder;
-  private final SagaTaskFactory sagaTaskFactory;
-
-  public GraphBasedSagaFactory(int retryDelay,
-      PersistentStore persistentStore,
-      FromJsonFormat<Set<String>> childrenExtractor,
-      ExecutorService executorService) {
-
-    this.childrenExtractor = childrenExtractor;
-    this.executorService = executorService;
-    this.sagaTaskFactory = new SagaTaskFactory(retryDelay, persistentStore);
-    this.graphBuilder = new GraphBuilder(new GraphCycleDetectorImpl<>());
-  }
-
-  @Override
-  public Saga createSaga(String requestJson, String sagaId, EventStore sagaLog, SagaDefinition definition) {
-    SagaContext sagaContext = new SagaContextImpl(childrenExtractor);
-
-    return new GraphBasedSaga(
-        sagaLog,
-        executorService,
-        sagaTaskFactory.sagaTasks(sagaId,
-            requestJson,
-            definition.policy(),
-            new ContextAwareEventStore(sagaLog, sagaContext)
-        ),
-        sagaContext,
-        graphBuilder.build(definition.requests()));
-  }
-
-  @Override
-  public boolean isTerminated() {
-    return !isRunning.get();
-  }
-
-  @Override
-  public void terminate() throws Exception {
-    isRunning.compareAndSet(true, false);
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/GraphBuilder.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/GraphBuilder.java
deleted file mode 100644
index 578cbb9b..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/GraphBuilder.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * 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.core.dag;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.servicecomb.saga.core.NoOpSagaRequest;
-import org.apache.servicecomb.saga.core.SagaException;
-import org.apache.servicecomb.saga.core.SagaRequest;
-
-import kamon.annotation.EnableKamon;
-import kamon.annotation.Segment;
-
-@EnableKamon
-public class GraphBuilder {
-
-  private final GraphCycleDetector<SagaRequest> detector;
-
-  public GraphBuilder(GraphCycleDetector<SagaRequest> detector) {
-    this.detector = detector;
-  }
-
-  @Segment(name = "buildGraph", category = "application", library = "kamon")
-  public SingleLeafDirectedAcyclicGraph<SagaRequest> build(SagaRequest[] sagaRequests) {
-    Map<String, Node<SagaRequest>> requestNodes = requestsToNodes(sagaRequests);
-
-    SingleLeafDirectedAcyclicGraph<SagaRequest> graph = linkNodesToGraph(sagaRequests, requestNodes);
-    detectCycle(graph);
-    return graph;
-  }
-
-  private SingleLeafDirectedAcyclicGraph<SagaRequest> linkNodesToGraph(
-      SagaRequest[] sagaRequests,
-      Map<String, Node<SagaRequest>> requestNodes) {
-
-    Node<SagaRequest> root = rootNode(0);
-    Node<SagaRequest> leaf = leafNode(sagaRequests.length + 1);
-
-    for (SagaRequest sagaRequest : sagaRequests) {
-      if (isOrphan(sagaRequest)) {
-        root.addChild(requestNodes.get(sagaRequest.id()));
-      } else {
-        for (String parent : sagaRequest.parents()) {
-          requestNodes.get(parent).addChild(requestNodes.get(sagaRequest.id()));
-        }
-      }
-    }
-
-    requestNodes.values().stream()
-        .filter((node) -> node.children().isEmpty())
-        .forEach(node -> node.addChild(leaf));
-
-    return new SingleLeafDirectedAcyclicGraph<>(root, leaf);
-  }
-
-  private Node<SagaRequest> rootNode(int id) {
-    return new Node<>(
-        id,
-        NoOpSagaRequest.SAGA_START_REQUEST);
-  }
-
-  private Node<SagaRequest> leafNode(int id) {
-    return new Node<>(
-        id,
-        NoOpSagaRequest.SAGA_END_REQUEST);
-  }
-
-  private boolean isOrphan(SagaRequest sagaRequest) {
-    return sagaRequest.parents().length == 0;
-  }
-
-  private Map<String, Node<SagaRequest>> requestsToNodes(SagaRequest[] sagaRequests) {
-    long index = 1;
-    Map<String, Node<SagaRequest>> requestMap = new HashMap<>();
-    for (SagaRequest sagaRequest : sagaRequests) {
-      if (requestMap.containsKey(sagaRequest.id())) {
-        // TODO: 8/20/2017 add random id if user didn't provide one
-        throw new SagaException("Failed to interpret requests with duplicate request id: " + sagaRequest.id());
-      }
-      requestMap.put(sagaRequest.id(), new Node<>(index++, sagaRequest));
-    }
-    return requestMap;
-  }
-
-  private void detectCycle(SingleLeafDirectedAcyclicGraph<SagaRequest> graph) {
-    Set<Node<SagaRequest>> jointNodes = detector.cycleJoints(graph);
-
-    if (!jointNodes.isEmpty()) {
-      throw new SagaException("Cycle detected in the request graph at nodes " + jointNodes);
-    }
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/GraphCycleDetector.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/GraphCycleDetector.java
deleted file mode 100644
index 9b12bc88..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/GraphCycleDetector.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.core.dag;
-
-import java.util.Set;
-
-public interface GraphCycleDetector<T> {
-
-  Set<Node<T>> cycleJoints(SingleLeafDirectedAcyclicGraph<T> graph);
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/GraphCycleDetectorImpl.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/GraphCycleDetectorImpl.java
deleted file mode 100644
index 6011a98d..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/GraphCycleDetectorImpl.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.core.dag;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Queue;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-/**
- * Cycle detection is based on topological sort with Kahn's algorithm.
- *
- * @see <a href="https://en.wikipedia.org/wiki/Topological_sorting">Topological Sorting</a>
- */
-public class GraphCycleDetectorImpl<T> implements GraphCycleDetector<T> {
-
-  @Override
-  public Set<Node<T>> cycleJoints(SingleLeafDirectedAcyclicGraph<T> graph) {
-    Queue<Node<T>> orphanNodes = new LinkedList<>();
-    Map<Node<T>, Set<Node<T>>> nodeParents = new HashMap<>();
-
-    orphanNodes.add(graph.root());
-
-    traverse(orphanNodes, nodeParents);
-
-    return unvisitedNodes(nodeParents);
-  }
-
-  private void traverse(Queue<Node<T>> orphanNodes, Map<Node<T>, Set<Node<T>>> nodeParents) {
-    while (!orphanNodes.isEmpty()) {
-      Node<T> node = orphanNodes.poll();
-
-      node.children().forEach(child -> {
-        nodeParents.computeIfAbsent(child, n -> new HashSet<>(child.parents()))
-            .remove(node);
-
-        if (nodeParents.get(child).isEmpty()) {
-          orphanNodes.add(child);
-        }
-      });
-    }
-  }
-
-  private Set<Node<T>> unvisitedNodes(Map<Node<T>, Set<Node<T>>> nodeParents) {
-    return nodeParents.entrySet()
-        .parallelStream()
-        .filter(parents -> !parents.getValue().isEmpty())
-        .map(Entry::getKey)
-        .collect(Collectors.toSet());
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/Node.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/Node.java
deleted file mode 100644
index 0b3be0a3..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/Node.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.core.dag;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Objects;
-import java.util.Set;
-
-public class Node<T> {
-  private final long id;
-  private final T value;
-  private final Set<Node<T>> children = new HashSet<>();
-  private final Set<Node<T>> parents = new HashSet<>();
-
-  public Node(long id, T value) {
-    this.id = id;
-    this.value = value;
-  }
-
-  long id() {
-    return id;
-  }
-
-  public T value() {
-    return value;
-  }
-
-  Set<Node<T>> parents() {
-    return parents;
-  }
-
-  public Set<Node<T>> children() {
-    return children;
-  }
-
-  public void addChild(Node<T> node) {
-    children.add(node);
-    node.parents.add(this);
-  }
-
-  public void addChildren(Collection<Node<T>> nodes) {
-    children.addAll(nodes);
-    nodes.forEach(node -> node.parents.add(this));
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || getClass() != o.getClass()) {
-      return false;
-    }
-    Node<?> node = (Node<?>) o;
-    return id == node.id;
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hash(id);
-  }
-
-  @Override
-  public String toString() {
-    return "Node{" +
-        "id=" + id +
-        ", value=" + value +
-        '}';
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/SingleLeafDirectedAcyclicGraph.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/SingleLeafDirectedAcyclicGraph.java
deleted file mode 100644
index cf0d19b1..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/SingleLeafDirectedAcyclicGraph.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.core.dag;
-
-public class SingleLeafDirectedAcyclicGraph<T> {
-
-  private final Node<T> root;
-  private final Node<T> leaf;
-
-  public SingleLeafDirectedAcyclicGraph(Node<T> root, Node<T> leaf) {
-
-    this.root = root;
-    this.leaf = leaf;
-  }
-
-  public Node<T> root() {
-    return root;
-  }
-
-  Node<T> leaf() {
-    return leaf;
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/Traveller.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/Traveller.java
deleted file mode 100644
index e44848be..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/Traveller.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.core.dag;
-
-import java.util.Collection;
-
-public interface Traveller<T> {
-
-  void next();
-
-  boolean hasNext();
-
-  Collection<Node<T>> nodes();
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/TraversalDirection.java b/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/TraversalDirection.java
deleted file mode 100644
index 22f73431..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/core/dag/TraversalDirection.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.core.dag;
-
-import java.util.Set;
-
-public interface TraversalDirection<T> {
-
-  Node<T> root(SingleLeafDirectedAcyclicGraph<T> dag);
-
-  Set<Node<T>> parents(Node<T> node);
-
-  Set<Node<T>> children(Node<T> node);
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/infrastructure/ContextAwareEventStore.java b/saga-core/src/main/java/org/apache/servicecomb/saga/infrastructure/ContextAwareEventStore.java
deleted file mode 100644
index 40fa71d1..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/infrastructure/ContextAwareEventStore.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.infrastructure;
-
-import java.util.Iterator;
-
-import org.apache.servicecomb.saga.core.EventEnvelope;
-import org.apache.servicecomb.saga.core.EventStore;
-import org.apache.servicecomb.saga.core.SagaContext;
-import org.apache.servicecomb.saga.core.SagaEvent;
-
-public class ContextAwareEventStore implements EventStore {
-  private final EventStore eventStore;
-  private final SagaContext sagaContext;
-
-  public ContextAwareEventStore(EventStore eventStore, SagaContext sagaContext) {
-    this.eventStore = eventStore;
-    this.sagaContext = sagaContext;
-  }
-
-  @Override
-  public void offer(SagaEvent sagaEvent) {
-    sagaEvent.gatherTo(sagaContext);
-    eventStore.offer(sagaEvent);
-  }
-
-  @Override
-  public void populate(Iterable<EventEnvelope> events) {
-    eventStore.populate(events);
-  }
-
-  @Override
-  public long size() {
-    return eventStore.size();
-  }
-
-  @Override
-  public Iterator<SagaEvent> iterator() {
-    return eventStore.iterator();
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/infrastructure/EmbeddedEventStore.java b/saga-core/src/main/java/org/apache/servicecomb/saga/infrastructure/EmbeddedEventStore.java
deleted file mode 100644
index d3422643..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/infrastructure/EmbeddedEventStore.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.infrastructure;
-
-import java.lang.invoke.MethodHandles;
-import java.util.Iterator;
-import java.util.Queue;
-import java.util.concurrent.LinkedBlockingQueue;
-
-import org.apache.servicecomb.saga.core.EventEnvelope;
-import org.apache.servicecomb.saga.core.EventStore;
-import org.apache.servicecomb.saga.core.SagaEvent;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class EmbeddedEventStore implements EventStore {
-  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-  private final Queue<SagaEvent> events = new LinkedBlockingQueue<>();
-
-  @Override
-  public void offer(SagaEvent sagaEvent) {
-    events.offer(sagaEvent);
-    log.info("Added event {}", sagaEvent);
-  }
-
-  @Override
-  public void populate(Iterable<EventEnvelope> events) {
-    for (EventEnvelope event : events) {
-      this.events.offer(event.event);
-      log.info("Populated event {}", event);
-    }
-  }
-
-  @Override
-  public long size() {
-    return events.size();
-  }
-
-  @Override
-  public Iterator<SagaEvent> iterator() {
-    return events.iterator();
-  }
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/transports/RestTransport.java b/saga-core/src/main/java/org/apache/servicecomb/saga/transports/RestTransport.java
deleted file mode 100644
index 3d5bda39..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/transports/RestTransport.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.transports;
-
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.apache.servicecomb.saga.core.Transport;
-import java.util.Map;
-
-public interface RestTransport extends Transport {
-
-  SagaResponse with(String address, String path, String method, Map<String, Map<String, String>> params);
-}
diff --git a/saga-core/src/main/java/org/apache/servicecomb/saga/transports/TransportFactory.java b/saga-core/src/main/java/org/apache/servicecomb/saga/transports/TransportFactory.java
deleted file mode 100644
index b34b5bdf..00000000
--- a/saga-core/src/main/java/org/apache/servicecomb/saga/transports/TransportFactory.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.transports;
-
-public interface TransportFactory {
-
-  RestTransport restTransport();
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/BackwardRecoveryTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/BackwardRecoveryTest.java
deleted file mode 100644
index 4f039928..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/BackwardRecoveryTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.core;
-
-import static com.seanyinx.github.unit.scaffolding.AssertUtils.expectFailing;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class BackwardRecoveryTest {
-
-  private final String serviceName = "aaa";
-  private final Transaction transaction = mock(Transaction.class);
-  private final SagaTask sagaTask = mock(SagaTask.class);
-  private final SagaRequest sagaRequest = mock(SagaRequest.class);
-  private final SagaResponse parentResponse = mock(SagaResponse.class);
-  private final BackwardRecovery backwardRecovery = new BackwardRecovery();
-  private final RuntimeException exception = new RuntimeException("oops");
-
-  @Before
-  public void setUp() throws Exception {
-    when(sagaRequest.serviceName()).thenReturn(serviceName);
-    when(sagaRequest.transaction()).thenReturn(transaction);
-  }
-
-  @Test
-  public void blowsUpWhenTaskIsNotCommitted() {
-    doThrow(exception).when(transaction).send(serviceName, parentResponse);
-
-    try {
-      backwardRecovery.apply(sagaTask, sagaRequest, parentResponse);
-      expectFailing(RuntimeException.class);
-    } catch (RuntimeException ignored) {
-    }
-
-    verify(sagaTask).abort(sagaRequest, exception);
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/CompensationImpl.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/CompensationImpl.java
deleted file mode 100644
index c974bc42..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/CompensationImpl.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.core;
-
-import java.util.Map;
-
-public class CompensationImpl extends RestOperation implements Compensation {
-
-  public CompensationImpl(String path, String method, Map<String, Map<String, String>> params) {
-    super(path, method, params);
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/CompositeSagaLogTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/CompositeSagaLogTest.java
deleted file mode 100644
index c7dea517..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/CompositeSagaLogTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.core;
-
-import static com.seanyinx.github.unit.scaffolding.AssertUtils.expectFailing;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-import org.junit.Test;
-
-public class CompositeSagaLogTest {
-
-  private final SagaRequest request = mock(SagaRequest.class);
-  private final DummyEvent sagaEvent = new DummyEvent(request);
-  private final SagaLog embedded = mock(SagaLog.class);
-  private final SagaLog persistent = mock(SagaLog.class);
-
-  private final SagaLog compositeSagaLog = new CompositeSagaLog(embedded, persistent);
-
-  @Test
-  public void addsLogsToEmbeddedOnlyAfterPersisted() {
-    doThrow(RuntimeException.class).when(persistent).offer(sagaEvent);
-
-    try {
-      compositeSagaLog.offer(sagaEvent);
-      expectFailing(RuntimeException.class);
-    } catch (RuntimeException ignored) {
-    }
-
-    verify(embedded, never()).offer(sagaEvent);
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/CompositeSagaResponseTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/CompositeSagaResponseTest.java
deleted file mode 100644
index be4b9f4d..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/CompositeSagaResponseTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.core;
-
-import static java.util.Arrays.asList;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.when;
-
-import org.junit.Test;
-import org.mockito.Mockito;
-
-public class CompositeSagaResponseTest {
-
-  private final SagaResponse response1 = Mockito.mock(SagaResponse.class);
-  private final SagaResponse response2 = Mockito.mock(SagaResponse.class);
-
-  private final SagaResponse compositeSagaResponse = new CompositeSagaResponse(asList(response1, response2));
-
-  @Test
-  public void succeededOnlyWhenAllAreSuccessful() throws Exception {
-    when(response1.succeeded()).thenReturn(true);
-    when(response2.succeeded()).thenReturn(true);
-
-    assertThat(compositeSagaResponse.succeeded(), is(true));
-  }
-
-  @Test
-  public void failedWhenAnyIsNotSuccessful() throws Exception {
-    when(response1.succeeded()).thenReturn(true);
-    when(response2.succeeded()).thenReturn(false);
-
-    assertThat(compositeSagaResponse.succeeded(), is(false));
-  }
-
-  @Test
-  public void bodyCombinesAllResponseBodies() throws Exception {
-    when(response1.body()).thenReturn("{\n"
-        + "  \"status\": 500,\n"
-        + "  \"body\" : \"oops\"\n"
-        + "}\n");
-
-    when(response2.body()).thenReturn("{\n"
-        + "  \"status\": 200,\n"
-        + "  \"body\" : \"blah\"\n"
-        + "}\n");
-
-    assertThat(compositeSagaResponse.body(), is("[{\n"
-        + "  \"status\": 500,\n"
-        + "  \"body\" : \"oops\"\n"
-        + "}\n"
-        + ", {\n"
-        + "  \"status\": 200,\n"
-        + "  \"body\" : \"blah\"\n"
-        + "}\n"
-        + "]"));
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/DummyEvent.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/DummyEvent.java
deleted file mode 100644
index c775afe5..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/DummyEvent.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.core;
-
-public class DummyEvent extends SagaEvent {
-
-  DummyEvent(SagaRequest payload) {
-    super("0", payload);
-  }
-
-  @Override
-  public void gatherTo(EventContext sagaContext) {
-
-  }
-
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/FallbackPolicyTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/FallbackPolicyTest.java
deleted file mode 100644
index a2d1f32b..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/FallbackPolicyTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.core;
-
-import static com.seanyinx.github.unit.scaffolding.Randomness.uniquify;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-public class FallbackPolicyTest {
-
-  private final int numberOfRetries = 3;
-  private final String address = uniquify("address");
-
-  private final SagaResponse success = Mockito.mock(SagaResponse.class);
-  private final SagaResponse failure = Mockito.mock(SagaResponse.class);
-  private final Fallback fallback = Mockito.mock(Fallback.class);
-  private final Compensation compensation = Mockito.mock(Compensation.class);
-  private final FallbackPolicy fallbackPolicy = new FallbackPolicy(100);
-
-  @SuppressWarnings("ThrowableInstanceNeverThrown")
-  private final RuntimeException exception = new RuntimeException("oops");
-
-  @Before
-  public void setUp() throws Exception {
-    when(compensation.retries()).thenReturn(numberOfRetries);
-    when(fallback.send(address)).thenReturn(failure);
-  }
-
-  @Test
-  public void retriesTransportForSpecifiedTimes() {
-    when(compensation.send(address))
-        .thenThrow(exception)
-        .thenThrow(exception)
-        .thenReturn(success);
-
-    SagaResponse response = fallbackPolicy.apply(address, compensation, fallback);
-
-    assertThat(response, is(success));
-    verify(compensation, times(3)).send(address);
-  }
-
-  @Test
-  public void fallbackIfTransportFailedWithRetry() {
-    when(compensation.send(address)).thenThrow(exception);
-
-    SagaResponse response = fallbackPolicy.apply(address, compensation, fallback);
-    assertThat(response, is(failure));
-
-    verify(compensation, times(numberOfRetries + 1)).send(address);
-    verify(fallback).send(address);
-  }
-
-  @Test
-  public void retryUntilSuccessIfNumberOfRetriesIsNegative() throws InterruptedException {
-    reset(compensation);
-    when(compensation.retries()).thenReturn(-1);
-    when(compensation.send(address))
-        .thenThrow(exception, exception, exception, exception, exception)
-        .thenReturn(success);
-
-    SagaResponse response = fallbackPolicy.apply(address, compensation, fallback);
-
-    assertThat(response, is(success));
-    verify(fallback, never()).send(anyString());
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/ForwardRecoveryTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/ForwardRecoveryTest.java
deleted file mode 100644
index e7651701..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/ForwardRecoveryTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.core;
-
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class ForwardRecoveryTest {
-
-  private final SagaTask sagaTask = mock(SagaTask.class);
-
-  private final Transaction transaction = mock(Transaction.class);
-  private final SagaRequest sagaRequest = mock(SagaRequest.class);
-  private final SagaResponse parentResponse = mock(SagaResponse.class);
-
-  private final ForwardRecovery forwardRecovery = new ForwardRecovery();
-
-  private final String serviceName = "aaa";
-
-  @Before
-  public void setUp() throws Exception {
-    when(sagaRequest.serviceName()).thenReturn(serviceName);
-    when(sagaRequest.transaction()).thenReturn(transaction);
-    when(sagaRequest.failRetryDelayMilliseconds()).thenReturn(300);
-  }
-
-  @Test
-  public void blowsUpWhenTaskIsNotCommittedWithFailRetryDelaySeconds() throws Exception {
-    doThrow(Exception.class).when(transaction).send(serviceName, parentResponse);
-
-    Thread t = new Thread(() -> forwardRecovery.apply(sagaTask, sagaRequest, parentResponse));
-    t.start();
-    Thread.sleep(400);
-    t.interrupt();
-
-    verify(transaction, times(2)).send(serviceName, parentResponse);
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/LongIdGeneratorTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/LongIdGeneratorTest.java
deleted file mode 100644
index 775866b6..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/LongIdGeneratorTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.core;
-
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-
-import org.junit.Test;
-
-public class LongIdGeneratorTest {
-
-
-  private final LongIdGenerator generator = new LongIdGenerator();
-
-  @Test
-  public void generatesLongInSequence() {
-    for (long index = 0; index < 10; index++) {
-      assertThat(generator.nextId(), is(index + 1));
-    }
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/RestOperationTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/RestOperationTest.java
deleted file mode 100644
index 7f1990d1..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/RestOperationTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.core;
-
-import static com.seanyinx.github.unit.scaffolding.AssertUtils.expectFailing;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonMap;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-
-import org.junit.Test;
-
-public class RestOperationTest {
-
-  @Test
-  public void blowsUpWhenGetMethodWithForm() {
-    try {
-      new RestOperation("blah", "GET", singletonMap("form", emptyMap()));
-      expectFailing(IllegalArgumentException.class);
-    } catch (IllegalArgumentException e) {
-      assertThat(e.getMessage(), is("GET & DELETE request cannot enclose a body"));
-    }
-  }
-
-  @Test
-  public void blowsUpWhenGetMethodWithJson() {
-    try {
-      new RestOperation("blah", "GET", singletonMap("json", emptyMap()));
-      expectFailing(IllegalArgumentException.class);
-    } catch (IllegalArgumentException e) {
-      assertThat(e.getMessage(), is("GET & DELETE request cannot enclose a body"));
-    }
-  }
-
-  @Test
-  public void blowsUpWhenDeleteMethodWithForm() {
-    try {
-      new RestOperation("blah", "DELETE", singletonMap("form", emptyMap()));
-      expectFailing(IllegalArgumentException.class);
-    } catch (IllegalArgumentException e) {
-      assertThat(e.getMessage(), is("GET & DELETE request cannot enclose a body"));
-    }
-  }
-
-  @Test
-  public void blowsUpWhenDeleteMethodWithJson() {
-    try {
-      new RestOperation("blah", "DELETE", singletonMap("json", emptyMap()));
-      expectFailing(IllegalArgumentException.class);
-    } catch (IllegalArgumentException e) {
-      assertThat(e.getMessage(), is("GET & DELETE request cannot enclose a body"));
-    }
-  }
-
-  @Test
-  public void blowsUpWhenMethodIsNotSupported() {
-    try {
-      new RestOperation("blah", "foo", emptyMap());
-      expectFailing(IllegalArgumentException.class);
-    } catch (IllegalArgumentException e) {
-      assertThat(e.getMessage(), is("Unsupported method foo"));
-    }
-  }
-
-  @Test
-  public void blowsUpWhenMethodIsNull() {
-    try {
-      new RestOperation("blah", null, emptyMap());
-      expectFailing(IllegalArgumentException.class);
-    } catch (IllegalArgumentException e) {
-      assertThat(e.getMessage(), is("Unsupported method null"));
-    }
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/RetrySagaLogTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/RetrySagaLogTest.java
deleted file mode 100644
index 6da8f16e..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/RetrySagaLogTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.core;
-
-
-import static org.awaitility.Awaitility.await;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
-import org.junit.Test;
-
-import org.apache.servicecomb.saga.core.SagaTaskFactory.RetrySagaLog;
-
-public class RetrySagaLogTest {
-
-  private final PersistentStore persistentStore = mock(PersistentStore.class);
-  private final SagaRequest sagaRequest = mock(SagaRequest.class);
-  private final SagaEvent dummyEvent = new DummyEvent(sagaRequest);
-  private final RetrySagaLog retrySagaLog = new RetrySagaLog(persistentStore, 100);
-
-  private volatile boolean interrupted = false;
-
-  @Test
-  public void retryUntilSuccessWhenEventIsNotPersisted() throws InterruptedException {
-    doThrow(RuntimeException.class).
-        doThrow(RuntimeException.class).
-        doThrow(RuntimeException.class).
-        doThrow(RuntimeException.class).
-        doThrow(RuntimeException.class).
-        doNothing().
-        when(persistentStore).offer(dummyEvent);
-
-    retrySagaLog.offer(dummyEvent);
-
-    verify(persistentStore, times(6)).offer(dummyEvent);
-  }
-
-  @Test
-  public void exitOnInterruption() throws InterruptedException {
-    ExecutorService executor = Executors.newSingleThreadExecutor();
-
-    Future<?> future = executor.submit(() -> {
-      doThrow(RuntimeException.class).when(persistentStore).offer(dummyEvent);
-
-      retrySagaLog.offer(dummyEvent);
-      interrupted = true;
-    });
-
-    Thread.sleep(500);
-
-    assertThat(future.cancel(true), is(true));
-
-    await().atMost(2, TimeUnit.SECONDS).until(() -> interrupted);
-    executor.shutdown();
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/SagaEndTaskTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/SagaEndTaskTest.java
deleted file mode 100644
index 22f5fa15..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/SagaEndTaskTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.core;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
-
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-
-public class SagaEndTaskTest {
-  private final SagaRequest request = mock(SagaRequest.class);
-  private final SagaLog sagaLog = mock(SagaLog.class);
-
-  private final String sagaId = "0";
-  private final SagaEndTask sagaEndTask = new SagaEndTask(sagaId, sagaLog);
-
-  @Test
-  public void emptyResponseOnSuccessfulEventPersistence() throws Exception {
-    ArgumentCaptor<SagaEndedEvent> argumentCaptor = ArgumentCaptor.forClass(SagaEndedEvent.class);
-    doNothing().when(sagaLog).offer(argumentCaptor.capture());
-
-    sagaEndTask.commit(request, SagaResponse.EMPTY_RESPONSE);
-
-    SagaEndedEvent event = argumentCaptor.getValue();
-    assertThat(event.sagaId, is(sagaId));
-    assertThat(event.json(null), is("{}"));
-    assertThat(event.payload(), is(request));
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/SagaEventMatcher.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/SagaEventMatcher.java
deleted file mode 100644
index 7e8289c7..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/SagaEventMatcher.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.core;
-
-import java.util.Objects;
-
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.hamcrest.TypeSafeMatcher;
-
-public class SagaEventMatcher extends TypeSafeMatcher<SagaEvent> {
-
-  private final String sagaId;
-  private final Operation operation;
-  private final Class<?> aClass;
-
-  public static Matcher<SagaEvent> eventWith(String sagaId, Operation operation, Class<?> aClass) {
-    return new SagaEventMatcher(sagaId, operation, aClass);
-  }
-
-  static Matcher<SagaEvent> eventWith(Operation operation, Class<?> aClass) {
-    return eventWith("0", operation, aClass);
-  }
-
-  private SagaEventMatcher(String sagaId, Operation operation, Class<?> aClass) {
-    this.sagaId = sagaId;
-    this.operation = operation;
-    this.aClass = aClass;
-  }
-
-  @Override
-  protected void describeMismatchSafely(SagaEvent item, Description description) {
-    description
-        .appendText("SagaEvent {sagaId=" + item.sagaId + ", operation=" + operation(item) + ", class=" + item.getClass());
-  }
-
-  @Override
-  protected boolean matchesSafely(SagaEvent envelope) {
-    return Objects.equals(envelope.sagaId, sagaId)
-        && operation(envelope).equals(operation)
-        && envelope.getClass().equals(aClass);
-  }
-
-  @Override
-  public void describeTo(Description description) {
-    description
-        .appendText("SagaEvent {sagaId=" + sagaId + ", operation=" + operation + ", class=" + aClass.getCanonicalName());
-  }
-
-  private Operation operation(SagaEvent envelope) {
-    return operation instanceof Compensation ? envelope.payload().compensation() : envelope.payload().transaction();
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/SagaExecutionComponentTestBase.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/SagaExecutionComponentTestBase.java
deleted file mode 100644
index b9e893f3..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/SagaExecutionComponentTestBase.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * 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.core;
-
-import static org.apache.servicecomb.saga.core.Operation.TYPE_REST;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonList;
-import static java.util.Collections.singletonMap;
-import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.awaitility.Awaitility.waitAtMost;
-import static org.hamcrest.Matchers.containsInAnyOrder;
-import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.when;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-
-import org.apache.servicecomb.saga.core.application.SagaFactory;
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.hamcrest.TypeSafeMatcher;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import org.apache.servicecomb.saga.core.application.SagaExecutionComponent;
-import org.apache.servicecomb.saga.core.application.interpreter.FromJsonFormat;
-import org.apache.servicecomb.saga.infrastructure.EmbeddedEventStore;
-
-@SuppressWarnings("unchecked")
-public abstract class SagaExecutionComponentTestBase {
-  private static final String requestJson = "[\n"
-      + "  {\n"
-      + "    \"id\": \"request-1\",\n"
-      + "    \"serviceName\": \"aaa\",\n"
-      + "    \"transaction\": {\n"
-      + "      \"method\": \"post\",\n"
-      + "      \"path\": \"/rest/as\"\n"
-      + "    },\n"
-      + "    \"compensation\": {\n"
-      + "      \"method\": \"delete\",\n"
-      + "      \"path\": \"/rest/as\"\n"
-      + "    }\n"
-      + "  }\n"
-      + "]\n";
-
-  private static final String sagaJson = "{\n"
-      + "  \"policy\": \"ForwardRecovery\",\n"
-      + "  \"requests\": " + requestJson + "\n"
-      + "}";
-
-  private static final String anotherRequestJson = "[\n"
-      + "  {\n"
-      + "    \"id\": \"request-2\",\n"
-      + "    \"serviceName\": \"bbb\",\n"
-      + "    \"transaction\": {\n"
-      + "      \"method\": \"post\",\n"
-      + "      \"path\": \"/rest/bs\"\n"
-      + "    },\n"
-      + "    \"compensation\": {\n"
-      + "      \"method\": \"delete\",\n"
-      + "      \"path\": \"/rest/bs\"\n"
-      + "    }\n"
-      + "  }\n"
-      + "]\n";
-
-  private static final String anotherSagaJson = "{\n"
-      + "  \"policy\": \"ForwardRecovery\",\n"
-      + "  \"requests\": " + anotherRequestJson + "\n"
-      + "}";
-
-  private final SagaRequest request1 = new SagaRequestImpl(
-      "request-1",
-      "aaa",
-      TYPE_REST,
-      new TransactionImpl("/rest/as", "post", emptyMap()),
-      new CompensationImpl("/rest/as", "delete", emptyMap())
-  );
-
-  private final SagaRequest request2 = new SagaRequestImpl(
-      "request-2",
-      "bbb",
-      TYPE_REST,
-      new TransactionImpl("/rest/bs", "post", emptyMap()),
-      new CompensationImpl("/rest/bs", "delete", emptyMap())
-  );
-
-  private final SagaDefinition definition1 = new SagaDefinition() {
-    @Override
-    public RecoveryPolicy policy() {
-      return new ForwardRecovery();
-    }
-
-    @Override
-    public SagaRequest[] requests() {
-      return new SagaRequest[]{request1};
-    }
-  };
-
-  private final SagaDefinition definition2 = new SagaDefinition() {
-    @Override
-    public RecoveryPolicy policy() {
-      return new BackwardRecovery();
-    }
-
-    @Override
-    public SagaRequest[] requests() {
-      return new SagaRequest[]{request2};
-    }
-  };
-
-  private final FromJsonFormat<SagaDefinition> fromJsonFormat = Mockito.mock(FromJsonFormat.class);
-  private final EmbeddedPersistentStore eventStore = new EmbeddedPersistentStore();
-
-  private final SagaExecutionComponent coordinator = new SagaExecutionComponent(
-      eventStore,
-      fromJsonFormat,
-      null,
-      sagaFactory(eventStore)
-  );
-
-  private final String sagaId = "1";
-
-  @Before
-  public void setUp() throws Exception {
-    when(fromJsonFormat.fromJson(sagaJson)).thenReturn(definition1);
-    when(fromJsonFormat.fromJson(anotherSagaJson)).thenReturn(definition2);
-  }
-
-  @Test
-  public void recoverSagaWithEventsFromEventStore() throws IOException {
-    eventStore.offer(new SagaStartedEvent(sagaId, sagaJson, NoOpSagaRequest.SAGA_START_REQUEST));
-    coordinator.reanimate();
-
-    assertThat(eventStore, contains(
-        eventWith(NoOpSagaRequest.SAGA_START_REQUEST, SagaStartedEvent.class),
-        eventWith(request1, TransactionStartedEvent.class),
-        eventWith(request1, TransactionEndedEvent.class),
-        eventWith(NoOpSagaRequest.SAGA_END_REQUEST, SagaEndedEvent.class)
-    ));
-  }
-
-  @Test
-  public void runSagaWithEventStore() throws IOException {
-    SagaResponse response = coordinator.run(sagaJson);
-
-    assertThat(response, is(SagaResponse.EMPTY_RESPONSE));
-    assertThat(eventStore, contains(
-        eventWith(NoOpSagaRequest.SAGA_START_REQUEST, SagaStartedEvent.class),
-        eventWith(request1, TransactionStartedEvent.class),
-        eventWith(request1, TransactionEndedEvent.class),
-        eventWith(NoOpSagaRequest.SAGA_END_REQUEST, SagaEndedEvent.class)
-    ));
-  }
-
-  @Test
-  public void processRequestsInParallel() {
-    CompletableFuture.runAsync(() -> coordinator.run(sagaJson));
-    CompletableFuture.runAsync(() -> coordinator.run(anotherSagaJson));
-
-    waitAtMost(2, SECONDS).until(() -> eventStore.size() == 8);
-
-    assertThat(eventStore, containsInAnyOrder(
-        eventWith(NoOpSagaRequest.SAGA_START_REQUEST, SagaStartedEvent.class),
-        eventWith(request1, TransactionStartedEvent.class),
-        eventWith(request1, TransactionEndedEvent.class),
-        eventWith(NoOpSagaRequest.SAGA_END_REQUEST, SagaEndedEvent.class),
-        eventWith(NoOpSagaRequest.SAGA_START_REQUEST, SagaStartedEvent.class),
-        eventWith(request2, TransactionStartedEvent.class),
-        eventWith(request2, TransactionEndedEvent.class),
-        eventWith(NoOpSagaRequest.SAGA_END_REQUEST, SagaEndedEvent.class)
-    ));
-  }
-
-  @Test
-  public void runSagaAfterRecovery() throws IOException {
-    eventStore.offer(new SagaStartedEvent(sagaId, sagaJson, NoOpSagaRequest.SAGA_START_REQUEST));
-    coordinator.reanimate();
-
-    coordinator.run(anotherSagaJson);
-
-    assertThat(eventStore, contains(
-        eventWith(NoOpSagaRequest.SAGA_START_REQUEST, SagaStartedEvent.class),
-        eventWith(request1, TransactionStartedEvent.class),
-        eventWith(request1, TransactionEndedEvent.class),
-        eventWith(NoOpSagaRequest.SAGA_END_REQUEST, SagaEndedEvent.class),
-        eventWith(NoOpSagaRequest.SAGA_START_REQUEST, SagaStartedEvent.class),
-        eventWith(request2, TransactionStartedEvent.class),
-        eventWith(request2, TransactionEndedEvent.class),
-        eventWith(NoOpSagaRequest.SAGA_END_REQUEST, SagaEndedEvent.class)
-    ));
-  }
-
-  private Matcher<SagaEvent> eventWith(
-      SagaRequest sagaRequest,
-      Class<?> type) {
-
-    return new TypeSafeMatcher<SagaEvent>() {
-      @Override
-      protected boolean matchesSafely(SagaEvent event) {
-        SagaRequest request = event.payload();
-        return sagaRequest.equals(request)
-            && event.getClass().equals(type);
-      }
-
-      @Override
-      protected void describeMismatchSafely(SagaEvent item, Description mismatchDescription) {
-        SagaRequest request = item.payload();
-        mismatchDescription.appendText(
-            "SagaEvent {" + request + "}");
-      }
-
-      @Override
-      public void describeTo(Description description) {
-        description.appendText(
-            "SagaEvent {" + sagaRequest + "}");
-      }
-    };
-  }
-
-  private class EmbeddedPersistentStore extends EmbeddedEventStore implements PersistentStore {
-
-    @Override
-    public Map<String, List<EventEnvelope>> findPendingSagaEvents() {
-      return singletonMap(sagaId, singletonList(
-          new EventEnvelope(1L, new SagaStartedEvent(sagaId, sagaJson, NoOpSagaRequest.SAGA_START_REQUEST))));
-    }
-  }
-
-  protected abstract SagaFactory sagaFactory(PersistentStore eventStore);
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/SagaIntegrationTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/SagaIntegrationTest.java
deleted file mode 100644
index d005ee7f..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/SagaIntegrationTest.java
+++ /dev/null
@@ -1,687 +0,0 @@
-/*
- * 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.core;
-
-import static com.seanyinx.github.unit.scaffolding.AssertUtils.expectFailing;
-import static org.apache.servicecomb.saga.core.Compensation.SAGA_START_COMPENSATION;
-import static org.apache.servicecomb.saga.core.Operation.TYPE_REST;
-import static org.apache.servicecomb.saga.core.SagaEventMatcher.eventWith;
-import static org.apache.servicecomb.saga.core.SagaResponse.EMPTY_RESPONSE;
-import static org.apache.servicecomb.saga.core.SagaResponse.NONE_RESPONSE;
-import static org.apache.servicecomb.saga.core.SagaTask.SAGA_END_TASK;
-import static org.apache.servicecomb.saga.core.SagaTask.SAGA_REQUEST_TASK;
-import static org.apache.servicecomb.saga.core.SagaTask.SAGA_START_TASK;
-import static org.apache.servicecomb.saga.core.Transaction.SAGA_END_TRANSACTION;
-import static org.apache.servicecomb.saga.core.Transaction.SAGA_START_TRANSACTION;
-import static java.util.Arrays.asList;
-import static java.util.Collections.emptySet;
-import static java.util.Collections.singletonList;
-import static org.hamcrest.Matchers.anyOf;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.CyclicBarrier;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.stubbing.Answer;
-
-import com.seanyinx.github.unit.scaffolding.Randomness;
-
-import org.apache.servicecomb.saga.core.application.interpreter.FromJsonFormat;
-import org.apache.servicecomb.saga.core.dag.Node;
-import org.apache.servicecomb.saga.core.dag.SingleLeafDirectedAcyclicGraph;
-import org.apache.servicecomb.saga.infrastructure.ContextAwareEventStore;
-import org.apache.servicecomb.saga.infrastructure.EmbeddedEventStore;
-
-@SuppressWarnings("unchecked")
-public class SagaIntegrationTest {
-  private static final String sagaId = Randomness.uniquify("sagaId");
-
-  private final FromJsonFormat<Set<String>> childrenExtractor = mock(FromJsonFormat.class);
-  private final SagaContext sagaContext = new SagaContextImpl(childrenExtractor);
-  private final IdGenerator<Long> idGenerator = new LongIdGenerator();
-  private final EventStore eventStore = new EmbeddedEventStore();
-  private final ContextAwareEventStore sagaLog = new ContextAwareEventStore(eventStore, sagaContext);
-
-  private final Transaction transaction1 = mock(Transaction.class, "transaction1");
-  private final Transaction transaction2 = mock(Transaction.class, "transaction2");
-  private final Transaction transaction3 = mock(Transaction.class, "transaction3");
-  private final Transaction transaction4 = mock(Transaction.class, "transaction4");
-
-  private final Compensation compensation1 = mock(Compensation.class, "compensation1");
-  private final Compensation compensation2 = mock(Compensation.class, "compensation2");
-  private final Compensation compensation3 = mock(Compensation.class, "compensation3");
-  private final Compensation compensation4 = mock(Compensation.class, "compensation4");
-
-  private final Fallback fallback1 = mock(Fallback.class, "fallback1");
-
-  private final String requestJson = "{}";
-  private final SagaRequest request1 = request("request1", "service1", transaction1, compensation1, fallback1);
-  private final SagaRequest request2 = request("request2", "service2", transaction2, compensation2, request1.id());
-  private final SagaRequest request3 = request("request3", "service3", transaction3, compensation3, request1.id());
-  private final SagaRequest request4 = request("request4", "service4", transaction4, compensation4, request3.id());
-
-  private final SagaResponse transactionResponse1 = new SuccessfulSagaResponse("transaction1");
-  private final SagaResponse transactionResponse2 = new SuccessfulSagaResponse("transaction2");
-  private final SagaResponse transactionResponse3 = new SuccessfulSagaResponse("transaction3");
-  private final SagaResponse compensationResponse1 = new SuccessfulSagaResponse("compensation1");
-  private final SagaResponse compensationResponse2 = new SuccessfulSagaResponse("compensation2");
-  private final SagaResponse compensationResponse3 = new SuccessfulSagaResponse("compensation3");
-
-  @SuppressWarnings("ThrowableInstanceNeverThrown")
-  private final RuntimeException exception = new RuntimeException("oops");
-
-  private final Node<SagaRequest> node1 = new Node<>(1, request1);
-  private final Node<SagaRequest> node2 = new Node<>(2, request2);
-  private final Node<SagaRequest> node3 = new Node<>(3, request3);
-  private final Node<SagaRequest> node4 = new Node<>(4, request4);
-  private final Node<SagaRequest> root = new Node<>(0, NoOpSagaRequest.SAGA_START_REQUEST);
-  private final Node<SagaRequest> leaf = new Node<>(5, NoOpSagaRequest.SAGA_END_REQUEST);
-  private final SingleLeafDirectedAcyclicGraph<SagaRequest> sagaTaskGraph = new SingleLeafDirectedAcyclicGraph<>(root, leaf);
-
-  private Saga saga;
-  private final Map<String, SagaTask> tasks = new HashMap<>();
-
-  // root - node1 - node2 - leaf
-  @Before
-  public void setUp() throws Exception {
-    when(childrenExtractor.fromJson(anyString())).thenReturn(emptySet());
-    when(childrenExtractor.fromJson(NONE_RESPONSE.body())).thenReturn(setOf("none"));
-
-    when(transaction1.send(request1.serviceName(), EMPTY_RESPONSE)).thenReturn(transactionResponse1);
-    when(transaction2.send(request2.serviceName(), transactionResponse1)).thenReturn(transactionResponse2);
-    when(transaction3.send(request3.serviceName(), transactionResponse1)).thenReturn(transactionResponse3);
-
-    when(compensation1.send(request1.serviceName(), compensationResponse2)).thenReturn(compensationResponse1);
-    when(compensation2.send(request2.serviceName(), compensationResponse3)).thenReturn(compensationResponse2);
-    when(compensation3.send(request3.serviceName(), EMPTY_RESPONSE)).thenReturn(compensationResponse3);
-
-    root.addChild(node1);
-    node1.addChild(node2);
-    node2.addChild(leaf);
-
-    SagaStartTask sagaStartTask = new SagaStartTask(sagaId, requestJson, sagaLog);
-    SagaEndTask sagaEndTask = new SagaEndTask(sagaId, sagaLog);
-    RequestProcessTask processTask = requestProcessTask(new BackwardRecovery());
-
-    tasks.put(SAGA_START_TASK, sagaStartTask);
-    tasks.put(SAGA_REQUEST_TASK, processTask);
-    tasks.put(SAGA_END_TASK, sagaEndTask);
-
-    saga = new GraphBasedSaga(eventStore, tasks, sagaContext, sagaTaskGraph);
-  }
-
-  @Test
-  public void transactionsAreRunSuccessfully() {
-    saga.run();
-
-    assertThat(eventStore, contains(
-        eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        eventWith(sagaId, transaction2, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction2, TransactionEndedEvent.class),
-        eventWith(sagaId, SAGA_END_TRANSACTION, SagaEndedEvent.class)
-    ));
-
-    verify(transaction1).send(request1.serviceName(), EMPTY_RESPONSE);
-    verify(transaction2).send(request2.serviceName(), transactionResponse1);
-
-    verify(compensation1, never()).send(request1.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-  }
-
-  // root - node1 - node2 - leaf
-  //             \_ node3 _/
-  @Test
-  public void compensateCommittedTransactionsOnFailure() {
-    addExtraChildToNode1();
-
-    // barrier to make sure the two transactions starts at the same time
-    CyclicBarrier barrier = new CyclicBarrier(2);
-    when(transaction2.send(request2.serviceName(), transactionResponse1))
-        .thenAnswer(
-            withAnswer(() -> {
-              barrier.await();
-              Thread.sleep(100);
-              throw exception;
-            }));
-
-    when(transaction3.send(request3.serviceName(), transactionResponse1))
-        .thenAnswer(
-            withAnswer(() -> {
-              barrier.await();
-              return transactionResponse3;
-            }));
-
-    saga.run();
-
-    assertThat(eventStore, contains(
-        eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        anyOf(eventWith(sagaId, transaction2, TransactionStartedEvent.class), eventWith(sagaId, transaction3, TransactionStartedEvent.class)),
-        anyOf(eventWith(sagaId, transaction2, TransactionStartedEvent.class), eventWith(sagaId, transaction3, TransactionStartedEvent.class)),
-        eventWith(sagaId, transaction3, TransactionEndedEvent.class),
-        eventWith(sagaId, transaction2, TransactionAbortedEvent.class),
-        eventWith(sagaId, compensation3, TransactionCompensatedEvent.class),
-        eventWith(sagaId, compensation1, TransactionCompensatedEvent.class),
-        eventWith(sagaId, SAGA_START_COMPENSATION, SagaEndedEvent.class)));
-
-    verify(transaction1).send(request1.serviceName(), EMPTY_RESPONSE);
-    verify(transaction2).send(request2.serviceName(), transactionResponse1);
-    verify(transaction3).send(request3.serviceName(), transactionResponse1);
-
-    verify(compensation1).send(request1.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-    verify(compensation3).send(request3.serviceName());
-  }
-
-  @Test
-  public void skipIgnoredTransaction() throws Exception {
-    addExtraChildToNode1();
-
-    when(childrenExtractor.fromJson(transactionResponse1.body())).thenReturn(setOf(request3.id()));
-
-    saga.run();
-
-    assertThat(eventStore, contains(
-        eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        eventWith(sagaId, transaction3, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction3, TransactionEndedEvent.class),
-        eventWith(sagaId, SAGA_END_TRANSACTION, SagaEndedEvent.class)
-    ));
-
-    verify(transaction1).send(request1.serviceName(), EMPTY_RESPONSE);
-    verify(transaction3).send(request3.serviceName(), transactionResponse1);
-    verify(transaction2, never()).send(anyString(), any(SagaResponse.class));
-
-    verify(compensation1, never()).send(request1.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-    verify(compensation3, never()).send(request3.serviceName());
-  }
-
-  @Test
-  public void skipAllIgnoredTransactions() throws Exception {
-    node1.addChild(node3);
-    node3.addChild(node4);
-    node4.addChild(leaf);
-
-    when(childrenExtractor.fromJson(transactionResponse1.body())).thenReturn(setOf("none"));
-
-    saga.run();
-
-    assertThat(eventStore, contains(
-        eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        eventWith(sagaId, SAGA_END_TRANSACTION, SagaEndedEvent.class)
-    ));
-
-    verify(transaction1).send(request1.serviceName(), EMPTY_RESPONSE);
-    verify(transaction2, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction3, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction4, never()).send(anyString(), any(SagaResponse.class));
-
-    verify(compensation1, never()).send(request1.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-    verify(compensation3, never()).send(request3.serviceName());
-    verify(compensation4, never()).send(request4.serviceName());
-  }
-
-  @Test
-  public void doNotCompensateIgnoredTransactions() throws Exception {
-    node1.addChild(node3);
-    node3.addChild(node4);
-    node4.addChild(leaf);
-
-    when(childrenExtractor.fromJson(transactionResponse1.body())).thenReturn(setOf(request3.id()));
-
-    when(transaction4.send(request4.serviceName(), transactionResponse3)).thenThrow(exception);
-
-    saga.run();
-
-    assertThat(eventStore, contains(
-        eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        eventWith(sagaId, transaction3, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction3, TransactionEndedEvent.class),
-        eventWith(sagaId, transaction4, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction4, TransactionAbortedEvent.class),
-        eventWith(sagaId, transaction3, TransactionCompensatedEvent.class),
-        eventWith(sagaId, transaction1, TransactionCompensatedEvent.class),
-        eventWith(sagaId, SAGA_START_COMPENSATION, SagaEndedEvent.class)
-    ));
-
-    verify(transaction1).send(request1.serviceName(), EMPTY_RESPONSE);
-    verify(transaction3).send(request3.serviceName(), transactionResponse1);
-    verify(transaction4).send(request4.serviceName(), transactionResponse3);
-    verify(transaction2, never()).send(anyString(), any(SagaResponse.class));
-
-    verify(compensation1).send(request1.serviceName());
-    verify(compensation3).send(request3.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-    verify(compensation4, never()).send(request4.serviceName());
-  }
-
-  // root - node1 - node2 - leaf
-  //             \_ node3 _/
-  @Test
-  public void redoHangingTransactionsOnFailure() throws InterruptedException {
-    addExtraChildToNode1();
-
-    // barrier to make sure the two transactions starts at the same time
-    CyclicBarrier barrier = new CyclicBarrier(2);
-    when(transaction3.send(request3.serviceName(), transactionResponse1))
-        .thenAnswer(withAnswer(() -> {
-      barrier.await();
-      throw exception;
-    }));
-
-    CountDownLatch latch = new CountDownLatch(1);
-
-    when(transaction2.send(request2.serviceName(), transactionResponse1))
-        .thenAnswer(withAnswer(() -> {
-      barrier.await();
-      latch.await();
-      return transactionResponse2;
-    })).thenReturn(transactionResponse2);
-
-    saga.run();
-
-    // the ordering of events may not be consistence due to concurrent processing of requests
-    assertThat(eventStore, contains(
-        eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        anyOf(
-            eventWith(sagaId, transaction2, TransactionStartedEvent.class),
-            eventWith(sagaId, transaction3, TransactionStartedEvent.class)),
-        anyOf(
-            eventWith(sagaId, transaction3, TransactionStartedEvent.class),
-            eventWith(sagaId, transaction2, TransactionStartedEvent.class)),
-        eventWith(sagaId, transaction3, TransactionAbortedEvent.class),
-        eventWith(sagaId, transaction2, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction2, TransactionEndedEvent.class),
-        eventWith(sagaId, compensation2, TransactionCompensatedEvent.class),
-        eventWith(sagaId, compensation1, TransactionCompensatedEvent.class),
-        eventWith(sagaId, SAGA_START_COMPENSATION, SagaEndedEvent.class)));
-
-    verify(transaction1).send(request1.serviceName(), EMPTY_RESPONSE);
-    verify(transaction2, times(2)).send(request2.serviceName(), transactionResponse1);
-    verify(transaction3).send(request3.serviceName(), transactionResponse1);
-
-    verify(compensation1).send(request1.serviceName());
-    verify(compensation2).send(request2.serviceName());
-    verify(compensation3, never()).send(request3.serviceName());
-
-    latch.countDown();
-  }
-
-  @Test
-  public void retriesFailedTransactionTillSuccess() {
-    RequestProcessTask processTask = requestProcessTask(new ForwardRecovery());
-    tasks.put(SAGA_REQUEST_TASK, processTask);
-
-    when(transaction2.send(request2.serviceName(), transactionResponse1))
-        .thenThrow(exception).thenThrow(exception).thenReturn(transactionResponse2);
-
-    saga.run();
-
-    assertThat(eventStore, contains(
-        eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        eventWith(sagaId, transaction2, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction2, TransactionEndedEvent.class),
-        eventWith(sagaId, SAGA_END_TRANSACTION, SagaEndedEvent.class)
-    ));
-
-    verify(transaction1).send(request1.serviceName(), EMPTY_RESPONSE);
-    verify(transaction2, times(3)).send(request2.serviceName(), transactionResponse1);
-
-    verify(compensation1, never()).send(anyString(), any(SagaResponse.class));
-    verify(compensation2, never()).send(anyString(), any(SagaResponse.class));
-  }
-
-  @Test
-  public void fallbackWhenCompensationFailed() {
-    int retries = 3;
-
-    when(transaction2.send(request2.serviceName(), transactionResponse1)).thenThrow(exception);
-    when(compensation1.send(request1.serviceName())).thenThrow(exception);
-    when(compensation1.retries()).thenReturn(retries);
-
-    saga.run();
-
-    verify(transaction1).send(request1.serviceName(), EMPTY_RESPONSE);
-    verify(transaction2).send(request2.serviceName(), transactionResponse1);
-
-    verify(compensation1, times(retries + 1)).send(request1.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-
-    verify(fallback1).send(request1.serviceName());
-  }
-
-  @Test
-  public void restoresSagaToTransactionStateByPlayingAllEvents() {
-    addExtraChildToNode1();
-
-    Iterable<EventEnvelope> events = asList(
-        envelope(new SagaStartedEvent(sagaId, requestJson, NoOpSagaRequest.SAGA_START_REQUEST)),
-        envelope(new TransactionStartedEvent(sagaId, request1)),
-        envelope(new TransactionEndedEvent(sagaId, request1, transactionResponse1)),
-        envelope(new TransactionStartedEvent(sagaId, request2)),
-        envelope(new TransactionEndedEvent(sagaId, request2, transactionResponse2))
-    );
-
-    eventStore.populate(events);
-    saga.play();
-
-    saga.run();
-    assertThat(eventStore, contains(
-        eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        eventWith(sagaId, transaction2, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction2, TransactionEndedEvent.class),
-        eventWith(sagaId, transaction3, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction3, TransactionEndedEvent.class),
-        eventWith(sagaId, SAGA_END_TRANSACTION, SagaEndedEvent.class)
-    ));
-
-    verify(transaction1, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction2, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction3).send(request3.serviceName(), transactionResponse1);
-
-    verify(compensation1, never()).send(request1.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-    verify(compensation3, never()).send(request3.serviceName());
-  }
-
-  @Test
-  public void restoresPartialTransactionByPlayingAllEvents() {
-    addExtraChildToNode1();
-
-    Iterable<EventEnvelope> events = asList(
-        envelope(new SagaStartedEvent(sagaId, requestJson, NoOpSagaRequest.SAGA_START_REQUEST)),
-        envelope(new TransactionStartedEvent(sagaId, request1)),
-        envelope(new TransactionEndedEvent(sagaId, request1, transactionResponse1)),
-        envelope(new TransactionStartedEvent(sagaId, request2)),
-        envelope(new TransactionEndedEvent(sagaId, request2, transactionResponse2)),
-        envelope(new TransactionStartedEvent(sagaId, request3))
-    );
-
-    eventStore.populate(events);
-    saga.play();
-
-    saga.run();
-    assertThat(eventStore, contains(
-        eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        eventWith(sagaId, transaction2, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction2, TransactionEndedEvent.class),
-        eventWith(sagaId, transaction3, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction3, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction3, TransactionEndedEvent.class),
-        eventWith(sagaId, SAGA_END_TRANSACTION, SagaEndedEvent.class)
-    ));
-
-    verify(transaction1, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction2, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction3).send(request3.serviceName(), transactionResponse1);
-
-    verify(compensation1, never()).send(request1.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-    verify(compensation3, never()).send(request3.serviceName());
-  }
-
-  @Test
-  public void restoresToCompensationFromAbortedTransactionByPlayingAllEvents() {
-    addExtraChildToNode1();
-
-    Iterable<EventEnvelope> events = asList(
-        envelope(new SagaStartedEvent(sagaId, requestJson, NoOpSagaRequest.SAGA_START_REQUEST)),
-        envelope(new TransactionStartedEvent(sagaId, request1)),
-        envelope(new TransactionEndedEvent(sagaId, request1)),
-        envelope(new TransactionStartedEvent(sagaId, request2)),
-        envelope(new TransactionEndedEvent(sagaId, request2)),
-        envelope(new TransactionStartedEvent(sagaId, request3)),
-        envelope(new TransactionAbortedEvent(sagaId, request3, exception))
-    );
-
-    eventStore.populate(events);
-    saga.play();
-
-    saga.run();
-    assertThat(eventStore, contains(
-        eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        eventWith(sagaId, transaction2, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction2, TransactionEndedEvent.class),
-        eventWith(sagaId, transaction3, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction3, TransactionAbortedEvent.class),
-        eventWith(sagaId, compensation2, TransactionCompensatedEvent.class),
-        eventWith(sagaId, compensation1, TransactionCompensatedEvent.class),
-        eventWith(sagaId, SAGA_START_COMPENSATION, SagaEndedEvent.class)
-    ));
-
-    verify(transaction1, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction2, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction3, never()).send(anyString(), any(SagaResponse.class));
-
-    verify(compensation1).send(request1.serviceName());
-    verify(compensation2).send(request2.serviceName());
-    verify(compensation3, never()).send(request3.serviceName());
-  }
-
-  @Test
-  public void restoresSagaToCompensationStateByPlayingAllEvents() {
-    addExtraChildToNode1();
-
-    Iterable<EventEnvelope> events = asList(
-        envelope(new SagaStartedEvent(sagaId, requestJson, NoOpSagaRequest.SAGA_START_REQUEST)),
-        envelope(new TransactionStartedEvent(sagaId, request1)),
-        envelope(new TransactionEndedEvent(sagaId, request1)),
-        envelope(new TransactionStartedEvent(sagaId, request2)),
-        envelope(new TransactionEndedEvent(sagaId, request2)),
-        envelope(new TransactionStartedEvent(sagaId, request3)),
-        envelope(new TransactionEndedEvent(sagaId, request3)),
-        envelope(new TransactionCompensatedEvent(sagaId, request2))
-    );
-
-    eventStore.populate(events);
-    saga.play();
-
-    saga.run();
-    assertThat(eventStore, contains(
-        eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        eventWith(sagaId, transaction2, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction2, TransactionEndedEvent.class),
-        eventWith(sagaId, transaction3, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction3, TransactionEndedEvent.class),
-        eventWith(sagaId, compensation2, TransactionCompensatedEvent.class),
-        eventWith(sagaId, compensation3, TransactionCompensatedEvent.class),
-        eventWith(sagaId, compensation1, TransactionCompensatedEvent.class),
-        eventWith(sagaId, SAGA_START_COMPENSATION, SagaEndedEvent.class)
-    ));
-
-    verify(transaction1, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction2, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction3, never()).send(anyString(), any(SagaResponse.class));
-
-    verify(compensation1).send(request1.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-    verify(compensation3).send(request3.serviceName());
-  }
-
-  @Test
-  public void restoresPartialCompensationByPlayingAllEvents() {
-    addExtraChildToNode1();
-
-    Iterable<EventEnvelope> events = asList(
-        envelope(new SagaStartedEvent(sagaId, requestJson, NoOpSagaRequest.SAGA_START_REQUEST)),
-        envelope(new TransactionStartedEvent(sagaId, request1)),
-        envelope(new TransactionEndedEvent(sagaId, request1)),
-        envelope(new TransactionStartedEvent(sagaId, request2)),
-        envelope(new TransactionEndedEvent(sagaId, request2)),
-        envelope(new TransactionStartedEvent(sagaId, request3)),
-        envelope(new TransactionAbortedEvent(sagaId, request3, exception)),
-        envelope(new TransactionCompensatedEvent(sagaId, request2))
-    );
-
-    eventStore.populate(events);
-    saga.play();
-
-    saga.run();
-    assertThat(eventStore, contains(
-        eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        eventWith(sagaId, transaction2, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction2, TransactionEndedEvent.class),
-        eventWith(sagaId, transaction3, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction3, TransactionAbortedEvent.class),
-        eventWith(sagaId, compensation2, TransactionCompensatedEvent.class),
-        eventWith(sagaId, compensation1, TransactionCompensatedEvent.class),
-        eventWith(sagaId, SAGA_START_COMPENSATION, SagaEndedEvent.class)
-    ));
-
-    verify(transaction1, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction2, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction3, never()).send(anyString(), any(SagaResponse.class));
-
-    verify(compensation1).send(request1.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-    verify(compensation3, never()).send(request3.serviceName());
-  }
-
-  @Test
-  public void restoresSagaToEndStateByPlayingAllEvents() {
-    Iterable<EventEnvelope> events = asList(
-        envelope(new SagaStartedEvent(sagaId, requestJson, NoOpSagaRequest.SAGA_START_REQUEST)),
-        envelope(new TransactionStartedEvent(sagaId, request1)),
-        envelope(new TransactionEndedEvent(sagaId, request1)),
-        envelope(new TransactionStartedEvent(sagaId, request2)),
-        envelope(new TransactionEndedEvent(sagaId, request2))
-    );
-
-    eventStore.populate(events);
-    saga.play();
-
-    saga.run();
-    assertThat(eventStore, contains(
-        eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        eventWith(sagaId, transaction2, TransactionStartedEvent.class),
-        eventWith(sagaId, transaction2, TransactionEndedEvent.class),
-        eventWith(sagaId, SAGA_END_TRANSACTION, SagaEndedEvent.class)
-    ));
-
-    verify(transaction1, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction2, never()).send(anyString(), any(SagaResponse.class));
-
-    verify(compensation1, never()).send(request1.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-  }
-
-  @Test
-  public void failFastIfSagaLogIsDown() throws Exception {
-    SagaLog sagaLog = mock(SagaLog.class);
-    tasks.put(SAGA_START_TASK, new SagaStartTask(sagaId, requestJson, sagaLog));
-
-    doThrow(RuntimeException.class).when(sagaLog).offer(any(SagaStartedEvent.class));
-
-    try {
-      saga.run();
-      expectFailing(SagaStartFailedException.class);
-    } catch (SagaStartFailedException e) {
-      assertThat(e.getMessage(), is("Failed to persist SagaStartedEvent for " + requestJson));
-    }
-
-    verify(sagaLog).offer(any(SagaStartedEvent.class));
-    verify(transaction1, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction2, never()).send(anyString(), any(SagaResponse.class));
-
-    verify(compensation1, never()).send(request1.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-  }
-
-  private Answer<SagaResponse> withAnswer(Callable<SagaResponse> callable) {
-    return invocationOnMock -> callable.call();
-  }
-
-  private EventEnvelope envelope(SagaEvent event) {
-    return new EventEnvelope(idGenerator.nextId(), event);
-  }
-
-  private void addExtraChildToNode1() {
-    node1.addChild(node3);
-    node3.addChild(leaf);
-  }
-
-  private SagaRequest request(String requestId,
-      String serviceName,
-      Transaction transaction,
-      Compensation compensation,
-      String... parentIds) {
-
-    return new SagaRequestImpl(requestId, serviceName, TYPE_REST, transaction, compensation, parentIds);
-  }
-
-  private SagaRequest request(String requestId,
-      String serviceName,
-      Transaction transaction,
-      Compensation compensation,
-      Fallback fallback) {
-
-    return new SagaRequestImpl(requestId, serviceName, TYPE_REST, transaction, compensation, fallback);
-  }
-
-  private HashSet<String> setOf(String requestId) {
-    return new HashSet<>(singletonList(requestId));
-  }
-
-  private RequestProcessTask requestProcessTask(RecoveryPolicy recoveryPolicy) {
-    return new RequestProcessTask(sagaId, sagaLog, recoveryPolicy, new FallbackPolicy(100));
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/SagaStartTaskTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/SagaStartTaskTest.java
deleted file mode 100644
index b1d0c4e4..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/SagaStartTaskTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.core;
-
-import static com.seanyinx.github.unit.scaffolding.AssertUtils.expectFailing;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.startsWith;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-
-public class SagaStartTaskTest {
-  private final SagaRequest request = mock(SagaRequest.class);
-  private final SagaLog sagaLog = mock(SagaLog.class);
-
-  private final String sagaId = "0";
-  private final String requestJson = null;
-  private final SagaStartTask sagaStartTask = new SagaStartTask(sagaId, requestJson, sagaLog);
-
-  @Test
-  public void emptyResponseOnSuccessfulEventPersistence() throws Exception {
-    ArgumentCaptor<SagaStartedEvent> argumentCaptor = ArgumentCaptor.forClass(SagaStartedEvent.class);
-    doNothing().when(sagaLog).offer(argumentCaptor.capture());
-
-    sagaStartTask.commit(request, SagaResponse.EMPTY_RESPONSE);
-
-    SagaStartedEvent event = argumentCaptor.getValue();
-    assertThat(event.sagaId, is(sagaId));
-    assertThat(event.json(null), is(requestJson));
-    assertThat(event.payload(), is(request));
-  }
-
-  @Test
-  public void blowsUpWhenEventIsNotPersisted() {
-    doThrow(RuntimeException.class).when(sagaLog).offer(any(SagaStartedEvent.class));
-
-    try {
-      sagaStartTask.commit(request, SagaResponse.EMPTY_RESPONSE);
-      expectFailing(SagaStartFailedException.class);
-    } catch (SagaStartFailedException e) {
-      assertThat(e.getMessage(), startsWith("Failed to persist SagaStartedEvent"));
-    }
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/TransactionImpl.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/TransactionImpl.java
deleted file mode 100644
index a59b1421..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/TransactionImpl.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.core;
-
-import java.util.Map;
-
-public class TransactionImpl extends RestOperation implements Transaction {
-
-  public TransactionImpl(String path, String method, Map<String, Map<String, String>> params) {
-    super(path, method, params);
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/actors/ActorBasedSagaExecutionComponentTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/actors/ActorBasedSagaExecutionComponentTest.java
deleted file mode 100644
index 01f8adbf..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/actors/ActorBasedSagaExecutionComponentTest.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.core.actors;
-
-import org.apache.servicecomb.saga.core.application.SagaFactory;
-import org.apache.servicecomb.saga.core.PersistentStore;
-import org.apache.servicecomb.saga.core.SagaExecutionComponentTestBase;
-
-
-public class ActorBasedSagaExecutionComponentTest extends SagaExecutionComponentTestBase {
-
-  @Override
-  protected SagaFactory sagaFactory(PersistentStore eventStore) {
-    return new ActorBasedSagaFactory(500, eventStore, null);
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/actors/ActorBasedSagaIntegrationTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/actors/ActorBasedSagaIntegrationTest.java
deleted file mode 100644
index ac649f06..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/actors/ActorBasedSagaIntegrationTest.java
+++ /dev/null
@@ -1,691 +0,0 @@
-/*
- * 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.core.actors;
-
-import static org.apache.servicecomb.saga.core.Transaction.SAGA_END_TRANSACTION;
-import static org.apache.servicecomb.saga.core.Transaction.SAGA_START_TRANSACTION;
-import static java.util.Arrays.asList;
-import static java.util.Collections.emptySet;
-import static java.util.Collections.singletonList;
-import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.hamcrest.CoreMatchers.anyOf;
-import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.CyclicBarrier;
-
-import org.apache.servicecomb.saga.core.Compensation;
-import org.apache.servicecomb.saga.core.EventEnvelope;
-import org.apache.servicecomb.saga.core.EventStore;
-import org.apache.servicecomb.saga.core.Fallback;
-import org.apache.servicecomb.saga.core.ForwardRecovery;
-import org.apache.servicecomb.saga.core.IdGenerator;
-import org.apache.servicecomb.saga.core.LongIdGenerator;
-import org.apache.servicecomb.saga.core.NoOpSagaRequest;
-import org.apache.servicecomb.saga.core.Operation;
-import org.apache.servicecomb.saga.core.Saga;
-import org.apache.servicecomb.saga.core.SagaEventMatcher;
-import org.apache.servicecomb.saga.core.SagaRequest;
-import org.apache.servicecomb.saga.core.SagaRequestImpl;
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.apache.servicecomb.saga.core.SagaStartedEvent;
-import org.apache.servicecomb.saga.core.SuccessfulSagaResponse;
-import org.apache.servicecomb.saga.core.TransactionCompensatedEvent;
-import org.apache.servicecomb.saga.core.TransactionStartedEvent;
-import org.apache.servicecomb.saga.core.application.SagaFactory;
-import org.hamcrest.CoreMatchers;
-import org.hamcrest.collection.IsIterableContainingInOrder;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.mockito.stubbing.Answer;
-
-import com.seanyinx.github.unit.scaffolding.Randomness;
-
-import org.apache.servicecomb.saga.core.BackwardRecovery;
-import org.apache.servicecomb.saga.core.PersistentStore;
-import org.apache.servicecomb.saga.core.SagaDefinition;
-import org.apache.servicecomb.saga.core.SagaEndedEvent;
-import org.apache.servicecomb.saga.core.SagaEvent;
-import org.apache.servicecomb.saga.core.Transaction;
-import org.apache.servicecomb.saga.core.TransactionAbortedEvent;
-import org.apache.servicecomb.saga.core.TransactionEndedEvent;
-import org.apache.servicecomb.saga.core.application.interpreter.FromJsonFormat;
-import org.apache.servicecomb.saga.infrastructure.EmbeddedEventStore;
-
-@SuppressWarnings("unchecked")
-public class ActorBasedSagaIntegrationTest {
-  private static final String sagaId = Randomness.uniquify("sagaId");
-
-  private final FromJsonFormat<Set<String>> childrenExtractor = mock(FromJsonFormat.class);
-  private final IdGenerator<Long> idGenerator = new LongIdGenerator();
-  private final EventStore eventStore = new EmbeddedEventStore();
-
-  private final PersistentStore persistentStore = mock(PersistentStore.class);
-  private final SagaDefinition sagaDefinition = mock(SagaDefinition.class);
-
-  private final Transaction transaction1 = mock(Transaction.class, "transaction1");
-  private final Transaction transaction2 = mock(Transaction.class, "transaction2");
-  private final Transaction transaction3 = mock(Transaction.class, "transaction3");
-  private final Transaction transaction4 = mock(Transaction.class, "transaction4");
-
-  private final Compensation compensation1 = mock(Compensation.class, "compensation1");
-  private final Compensation compensation2 = mock(Compensation.class, "compensation2");
-  private final Compensation compensation3 = mock(Compensation.class, "compensation3");
-  private final Compensation compensation4 = mock(Compensation.class, "compensation4");
-
-  private final Fallback fallback1 = mock(Fallback.class, "fallback1");
-
-  private final String requestJson = "{}";
-  private final SagaRequest request1 = request("request1", "service1", transaction1, compensation1, fallback1);
-  private final SagaRequest request2 = request("request2", "service2", transaction2, compensation2, request1.id());
-  private final SagaRequest request3 = request("request3", "service3", transaction3, compensation3, request1.id());
-  private final SagaRequest request4 = request("request4", "service4", transaction4, compensation4, request3.id());
-
-  private final SagaResponse transactionResponse1 = new SuccessfulSagaResponse("transaction1");
-  private final SagaResponse transactionResponse2 = new SuccessfulSagaResponse("transaction2");
-  private final SagaResponse transactionResponse3 = new SuccessfulSagaResponse("transaction3");
-  private final SagaResponse compensationResponse1 = new SuccessfulSagaResponse("compensation1");
-  private final SagaResponse compensationResponse2 = new SuccessfulSagaResponse("compensation2");
-  private final SagaResponse compensationResponse3 = new SuccessfulSagaResponse("compensation3");
-
-  @SuppressWarnings("ThrowableInstanceNeverThrown")
-  private final RuntimeException exception = new RuntimeException("oops");
-
-  private Saga saga;
-  private final SagaFactory sagaFactory = new ActorBasedSagaFactory(100, persistentStore, childrenExtractor);
-
-  // root - node1 - node2 - leaf
-  @Before
-  public void setUp() throws Exception {
-    when(sagaDefinition.policy()).thenReturn(new BackwardRecovery());
-    when(sagaDefinition.requests()).thenReturn(new SagaRequest[]{request1, request2});
-
-    when(childrenExtractor.fromJson(anyString())).thenReturn(emptySet());
-    when(childrenExtractor.fromJson(SagaResponse.NONE_RESPONSE.body())).thenReturn(setOf("none"));
-
-    when(transaction1.send(request1.serviceName(), SagaResponse.EMPTY_RESPONSE)).thenReturn(transactionResponse1);
-    when(transaction2.send(request2.serviceName(), transactionResponse1)).thenReturn(transactionResponse2);
-    when(transaction3.send(request3.serviceName(), transactionResponse1)).thenReturn(transactionResponse3);
-
-    when(compensation1.send(request1.serviceName(), compensationResponse2)).thenReturn(compensationResponse1);
-    when(compensation2.send(request2.serviceName(), compensationResponse3)).thenReturn(compensationResponse2);
-    when(compensation3.send(request3.serviceName(), SagaResponse.EMPTY_RESPONSE)).thenReturn(compensationResponse3);
-  }
-
-  @After
-  public void tearDown() throws Exception {
-    sagaFactory.terminate();
-    assertTrue(sagaFactory.isTerminated());
-  }
-
-  @Test
-  public void transactionsAreRunSuccessfully() {
-    saga = sagaFactory.createSaga(requestJson, sagaId, eventStore, sagaDefinition);
-    saga.run();
-
-    assertThat(eventStore, IsIterableContainingInOrder.contains(
-        SagaEventMatcher.eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction2, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction2, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, SAGA_END_TRANSACTION, SagaEndedEvent.class)
-    ));
-
-    verify(transaction1).send(request1.serviceName(), SagaResponse.EMPTY_RESPONSE);
-    verify(transaction2).send(request2.serviceName(), transactionResponse1);
-
-    verify(compensation1, never()).send(request1.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-  }
-
-  // root - node1 - node2 - leaf
-  //             \_ node3 _/
-  @Test
-  public void compensateCommittedTransactionsOnFailure() {
-    when(sagaDefinition.requests()).thenReturn(new SagaRequest[]{request1, request2, request3});
-    saga = sagaFactory.createSaga(requestJson, sagaId, eventStore, sagaDefinition);
-
-    // barrier to make sure the two transactions starts at the same time
-    CyclicBarrier barrier = new CyclicBarrier(2);
-    when(transaction2.send(request2.serviceName(), transactionResponse1))
-        .thenAnswer(
-            withAnswer(() -> {
-              barrier.await();
-              Thread.sleep(100);
-              throw exception;
-            }));
-
-    when(transaction3.send(request3.serviceName(), transactionResponse1))
-        .thenAnswer(
-            withAnswer(() -> {
-              barrier.await();
-              return transactionResponse3;
-            }));
-
-    saga.run();
-
-    assertThat(eventStore, IsIterableContainingInOrder.contains(
-        SagaEventMatcher.eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        CoreMatchers.anyOf(SagaEventMatcher.eventWith(sagaId, transaction2, TransactionStartedEvent.class), SagaEventMatcher
-            .eventWith(sagaId, transaction3, TransactionStartedEvent.class)),
-        CoreMatchers.anyOf(SagaEventMatcher.eventWith(sagaId, transaction2, TransactionStartedEvent.class), SagaEventMatcher
-            .eventWith(sagaId, transaction3, TransactionStartedEvent.class)),
-        SagaEventMatcher.eventWith(sagaId, transaction3, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction2, TransactionAbortedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, compensation3, TransactionCompensatedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, compensation1, TransactionCompensatedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, Compensation.SAGA_START_COMPENSATION, SagaEndedEvent.class)));
-
-    verify(transaction1).send(request1.serviceName(), SagaResponse.EMPTY_RESPONSE);
-    verify(transaction2).send(request2.serviceName(), transactionResponse1);
-    verify(transaction3).send(request3.serviceName(), transactionResponse1);
-
-    verify(compensation1).send(request1.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-    verify(compensation3).send(request3.serviceName());
-  }
-
-  @Test
-  public void skipIgnoredTransaction() throws Exception {
-    when(sagaDefinition.requests()).thenReturn(new SagaRequest[]{request1, request2, request3});
-    saga = sagaFactory.createSaga(requestJson, sagaId, eventStore, sagaDefinition);
-
-    when(childrenExtractor.fromJson(transactionResponse1.body())).thenReturn(setOf(request3.id()));
-
-    saga.run();
-
-    assertThat(eventStore, IsIterableContainingInOrder.contains(
-        SagaEventMatcher.eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction3, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction3, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, SAGA_END_TRANSACTION, SagaEndedEvent.class)
-    ));
-
-    verify(transaction1).send(request1.serviceName(), SagaResponse.EMPTY_RESPONSE);
-    verify(transaction3).send(request3.serviceName(), transactionResponse1);
-    verify(transaction2, never()).send(anyString(), any(SagaResponse.class));
-
-    verify(compensation1, never()).send(request1.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-    verify(compensation3, never()).send(request3.serviceName());
-  }
-
-  @Test
-  public void skipAllIgnoredTransactions() throws Exception {
-    when(sagaDefinition.requests()).thenReturn(new SagaRequest[]{request1, request2, request3, request4});
-    saga = sagaFactory.createSaga(requestJson, sagaId, eventStore, sagaDefinition);
-
-    when(childrenExtractor.fromJson(transactionResponse1.body())).thenReturn(setOf("none"));
-
-    saga.run();
-
-    assertThat(eventStore, IsIterableContainingInOrder.contains(
-        SagaEventMatcher.eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, SAGA_END_TRANSACTION, SagaEndedEvent.class)
-    ));
-
-    verify(transaction1).send(request1.serviceName(), SagaResponse.EMPTY_RESPONSE);
-    verify(transaction2, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction3, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction4, never()).send(anyString(), any(SagaResponse.class));
-
-    verify(compensation1, never()).send(request1.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-    verify(compensation3, never()).send(request3.serviceName());
-    verify(compensation4, never()).send(request4.serviceName());
-  }
-
-  @Test
-  public void doNotCompensateIgnoredTransactions() throws Exception {
-    when(sagaDefinition.requests()).thenReturn(new SagaRequest[]{request1, request2, request3, request4});
-    saga = sagaFactory.createSaga(requestJson, sagaId, eventStore, sagaDefinition);
-
-    when(childrenExtractor.fromJson(transactionResponse1.body())).thenReturn(setOf(request3.id()));
-
-    when(transaction4.send(request4.serviceName(), transactionResponse3)).thenThrow(exception);
-
-    saga.run();
-
-    assertThat(eventStore, IsIterableContainingInOrder.contains(
-        SagaEventMatcher.eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction3, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction3, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction4, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction4, TransactionAbortedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction3, TransactionCompensatedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionCompensatedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, Compensation.SAGA_START_COMPENSATION, SagaEndedEvent.class)
-    ));
-
-    verify(transaction1).send(request1.serviceName(), SagaResponse.EMPTY_RESPONSE);
-    verify(transaction3).send(request3.serviceName(), transactionResponse1);
-    verify(transaction4).send(request4.serviceName(), transactionResponse3);
-    verify(transaction2, never()).send(anyString(), any(SagaResponse.class));
-
-    verify(compensation1).send(request1.serviceName());
-    verify(compensation3).send(request3.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-    verify(compensation4, never()).send(request4.serviceName());
-  }
-
-  // TODO: 2017/10/31 actor will hang and its parent and children will be blocked without its response, timeout must be applied
-  @Ignore
-  // root - node1 - node2 - leaf
-  //             \_ node3 _/
-  @Test
-  public void redoHangingTransactionsOnFailure() throws InterruptedException {
-    when(sagaDefinition.requests()).thenReturn(new SagaRequest[]{request1, request2, request3});
-    saga = sagaFactory.createSaga(requestJson, sagaId, eventStore, sagaDefinition);
-
-    // barrier to make sure the two transactions starts at the same time
-    CyclicBarrier barrier = new CyclicBarrier(2);
-    when(transaction3.send(request3.serviceName(), transactionResponse1))
-        .thenAnswer(withAnswer(() -> {
-      barrier.await();
-      throw exception;
-    }));
-
-    CountDownLatch latch = new CountDownLatch(1);
-
-    when(transaction2.send(request2.serviceName(), transactionResponse1))
-        .thenAnswer(withAnswer(() -> {
-      barrier.await();
-      latch.await(1, SECONDS);
-      return transactionResponse2;
-    })).thenReturn(transactionResponse2);
-
-    saga.run();
-
-    // the ordering of events may not be consistence due to concurrent processing of requests
-    assertThat(eventStore, IsIterableContainingInOrder.contains(
-        SagaEventMatcher.eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        CoreMatchers.anyOf(
-            SagaEventMatcher.eventWith(sagaId, transaction2, TransactionStartedEvent.class),
-            SagaEventMatcher.eventWith(sagaId, transaction3, TransactionStartedEvent.class)),
-        CoreMatchers.anyOf(
-            SagaEventMatcher.eventWith(sagaId, transaction3, TransactionStartedEvent.class),
-            SagaEventMatcher.eventWith(sagaId, transaction2, TransactionStartedEvent.class)),
-        SagaEventMatcher.eventWith(sagaId, transaction3, TransactionAbortedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction2, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction2, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, compensation2, TransactionCompensatedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, compensation1, TransactionCompensatedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, Compensation.SAGA_START_COMPENSATION, SagaEndedEvent.class)));
-
-    verify(transaction1).send(request1.serviceName(), SagaResponse.EMPTY_RESPONSE);
-    verify(transaction2, times(2)).send(request2.serviceName(), transactionResponse1);
-    verify(transaction3).send(request3.serviceName(), transactionResponse1);
-
-    verify(compensation1).send(request1.serviceName());
-    verify(compensation2).send(request2.serviceName());
-    verify(compensation3, never()).send(request3.serviceName());
-
-    latch.countDown();
-  }
-
-  @Test
-  public void retriesFailedTransactionTillSuccess() {
-    when(sagaDefinition.policy()).thenReturn(new ForwardRecovery());
-    saga = sagaFactory.createSaga(requestJson, sagaId, eventStore, sagaDefinition);
-
-    when(transaction2.send(request2.serviceName(), transactionResponse1))
-        .thenThrow(exception).thenThrow(exception).thenReturn(transactionResponse2);
-
-    saga.run();
-
-    assertThat(eventStore, IsIterableContainingInOrder.contains(
-        SagaEventMatcher.eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction2, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction2, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, SAGA_END_TRANSACTION, SagaEndedEvent.class)
-    ));
-
-    verify(transaction1).send(request1.serviceName(), SagaResponse.EMPTY_RESPONSE);
-    verify(transaction2, times(3)).send(request2.serviceName(), transactionResponse1);
-
-    verify(compensation1, never()).send(anyString(), any(SagaResponse.class));
-    verify(compensation2, never()).send(anyString(), any(SagaResponse.class));
-  }
-
-  @Test
-  public void fallbackWhenCompensationFailed() {
-    int retries = 3;
-    saga = sagaFactory.createSaga(requestJson, sagaId, eventStore, sagaDefinition);
-
-    when(transaction2.send(request2.serviceName(), transactionResponse1)).thenThrow(exception);
-    when(compensation1.send(request1.serviceName())).thenThrow(exception);
-    when(compensation1.retries()).thenReturn(retries);
-
-    saga.run();
-
-    verify(transaction1).send(request1.serviceName(), SagaResponse.EMPTY_RESPONSE);
-    verify(transaction2).send(request2.serviceName(), transactionResponse1);
-
-    verify(compensation1, times(retries + 1)).send(request1.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-
-    verify(fallback1).send(request1.serviceName());
-  }
-
-  @Test
-  public void restoresSagaToTransactionStateByPlayingAllEvents() {
-    when(sagaDefinition.requests()).thenReturn(new SagaRequest[]{request1, request2, request3});
-    saga = sagaFactory.createSaga(requestJson, sagaId, eventStore, sagaDefinition);
-
-    Iterable<EventEnvelope> events = asList(
-        envelope(new SagaStartedEvent(sagaId, requestJson, NoOpSagaRequest.SAGA_START_REQUEST)),
-        envelope(new TransactionStartedEvent(sagaId, request1)),
-        envelope(new TransactionEndedEvent(sagaId, request1, transactionResponse1)),
-        envelope(new TransactionStartedEvent(sagaId, request2)),
-        envelope(new TransactionEndedEvent(sagaId, request2, transactionResponse2))
-    );
-
-    eventStore.populate(events);
-    saga.play();
-
-    saga.run();
-    assertThat(eventStore, IsIterableContainingInOrder.contains(
-        SagaEventMatcher.eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction2, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction2, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction3, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction3, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, SAGA_END_TRANSACTION, SagaEndedEvent.class)
-    ));
-
-    verify(transaction1, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction2, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction3).send(request3.serviceName(), transactionResponse1);
-
-    verify(compensation1, never()).send(request1.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-    verify(compensation3, never()).send(request3.serviceName());
-  }
-
-  @Test
-  public void restoresPartialTransactionByPlayingAllEvents() {
-    when(sagaDefinition.requests()).thenReturn(new SagaRequest[]{request1, request2, request3});
-    saga = sagaFactory.createSaga(requestJson, sagaId, eventStore, sagaDefinition);
-
-    Iterable<EventEnvelope> events = asList(
-        envelope(new SagaStartedEvent(sagaId, requestJson, NoOpSagaRequest.SAGA_START_REQUEST)),
-        envelope(new TransactionStartedEvent(sagaId, request1)),
-        envelope(new TransactionEndedEvent(sagaId, request1, transactionResponse1)),
-        envelope(new TransactionStartedEvent(sagaId, request2)),
-        envelope(new TransactionEndedEvent(sagaId, request2, transactionResponse2)),
-        envelope(new TransactionStartedEvent(sagaId, request3))
-    );
-
-    eventStore.populate(events);
-    saga.play();
-
-    saga.run();
-    assertThat(eventStore, IsIterableContainingInOrder.contains(
-        SagaEventMatcher.eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction2, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction2, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction3, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction3, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction3, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, SAGA_END_TRANSACTION, SagaEndedEvent.class)
-    ));
-
-    verify(transaction1, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction2, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction3).send(request3.serviceName(), transactionResponse1);
-
-    verify(compensation1, never()).send(request1.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-    verify(compensation3, never()).send(request3.serviceName());
-  }
-
-  @Test
-  public void restoresToCompensationFromAbortedTransactionByPlayingAllEvents() {
-    when(sagaDefinition.requests()).thenReturn(new SagaRequest[]{request1, request2, request3});
-    saga = sagaFactory.createSaga(requestJson, sagaId, eventStore, sagaDefinition);
-
-    Iterable<EventEnvelope> events = asList(
-        envelope(new SagaStartedEvent(sagaId, requestJson, NoOpSagaRequest.SAGA_START_REQUEST)),
-        envelope(new TransactionStartedEvent(sagaId, request1)),
-        envelope(new TransactionEndedEvent(sagaId, request1)),
-        envelope(new TransactionStartedEvent(sagaId, request2)),
-        envelope(new TransactionEndedEvent(sagaId, request2)),
-        envelope(new TransactionStartedEvent(sagaId, request3)),
-        envelope(new TransactionAbortedEvent(sagaId, request3, exception))
-    );
-
-    eventStore.populate(events);
-    saga.play();
-
-    saga.run();
-    assertThat(eventStore, IsIterableContainingInOrder.contains(
-        SagaEventMatcher.eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction2, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction2, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction3, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction3, TransactionAbortedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, compensation2, TransactionCompensatedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, compensation1, TransactionCompensatedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, Compensation.SAGA_START_COMPENSATION, SagaEndedEvent.class)
-    ));
-
-    verify(transaction1, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction2, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction3, never()).send(anyString(), any(SagaResponse.class));
-
-    verify(compensation1).send(request1.serviceName());
-    verify(compensation2).send(request2.serviceName());
-    verify(compensation3, never()).send(request3.serviceName());
-  }
-
-  @Test
-  public void restoresSagaToCompensationStateByPlayingAllEvents() {
-    when(sagaDefinition.requests()).thenReturn(new SagaRequest[]{request1, request2, request3});
-    saga = sagaFactory.createSaga(requestJson, sagaId, eventStore, sagaDefinition);
-
-    Iterable<EventEnvelope> events = asList(
-        envelope(new SagaStartedEvent(sagaId, requestJson, NoOpSagaRequest.SAGA_START_REQUEST)),
-        envelope(new TransactionStartedEvent(sagaId, request1)),
-        envelope(new TransactionEndedEvent(sagaId, request1)),
-        envelope(new TransactionStartedEvent(sagaId, request2)),
-        envelope(new TransactionEndedEvent(sagaId, request2)),
-        envelope(new TransactionStartedEvent(sagaId, request3)),
-        envelope(new TransactionAbortedEvent(sagaId, request3, exception)),
-        envelope(new TransactionCompensatedEvent(sagaId, request2))
-    );
-
-    eventStore.populate(events);
-    saga.play();
-
-    saga.run();
-    assertThat(eventStore, IsIterableContainingInOrder.contains(
-        SagaEventMatcher.eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction2, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction2, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction3, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction3, TransactionAbortedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, compensation2, TransactionCompensatedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, compensation1, TransactionCompensatedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, Compensation.SAGA_START_COMPENSATION, SagaEndedEvent.class)
-    ));
-
-    verify(transaction1, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction2, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction3, never()).send(anyString(), any(SagaResponse.class));
-
-    verify(compensation1).send(request1.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-    verify(compensation3, never()).send(request3.serviceName());
-  }
-
-  @Test
-  public void restoresPartialCompensationByPlayingAllEvents() {
-    when(sagaDefinition.requests()).thenReturn(new SagaRequest[]{request1, request2, request3});
-    saga = sagaFactory.createSaga(requestJson, sagaId, eventStore, sagaDefinition);
-
-    Iterable<EventEnvelope> events = asList(
-        envelope(new SagaStartedEvent(sagaId, requestJson, NoOpSagaRequest.SAGA_START_REQUEST)),
-        envelope(new TransactionStartedEvent(sagaId, request1)),
-        envelope(new TransactionEndedEvent(sagaId, request1)),
-        envelope(new TransactionStartedEvent(sagaId, request2)),
-        envelope(new TransactionEndedEvent(sagaId, request2)),
-        envelope(new TransactionStartedEvent(sagaId, request3)),
-        envelope(new TransactionAbortedEvent(sagaId, request3, exception)),
-        envelope(new TransactionCompensatedEvent(sagaId, request2))
-    );
-
-    eventStore.populate(events);
-    saga.play();
-
-    saga.run();
-    assertThat(eventStore, IsIterableContainingInOrder.contains(
-        SagaEventMatcher.eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction2, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction2, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction3, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction3, TransactionAbortedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, compensation2, TransactionCompensatedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, compensation1, TransactionCompensatedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, Compensation.SAGA_START_COMPENSATION, SagaEndedEvent.class)
-    ));
-
-    verify(transaction1, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction2, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction3, never()).send(anyString(), any(SagaResponse.class));
-
-    verify(compensation1).send(request1.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-    verify(compensation3, never()).send(request3.serviceName());
-  }
-
-  @Test
-  public void restoresSagaToEndStateByPlayingAllEvents() {
-    saga = sagaFactory.createSaga(requestJson, sagaId, eventStore, sagaDefinition);
-    Iterable<EventEnvelope> events = asList(
-        envelope(new SagaStartedEvent(sagaId, requestJson, NoOpSagaRequest.SAGA_START_REQUEST)),
-        envelope(new TransactionStartedEvent(sagaId, request1)),
-        envelope(new TransactionEndedEvent(sagaId, request1)),
-        envelope(new TransactionStartedEvent(sagaId, request2)),
-        envelope(new TransactionEndedEvent(sagaId, request2))
-    );
-
-    eventStore.populate(events);
-    saga.play();
-
-    saga.run();
-    assertThat(eventStore, IsIterableContainingInOrder.contains(
-        SagaEventMatcher.eventWith(sagaId, SAGA_START_TRANSACTION, SagaStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction1, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction2, TransactionStartedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, transaction2, TransactionEndedEvent.class),
-        SagaEventMatcher.eventWith(sagaId, SAGA_END_TRANSACTION, SagaEndedEvent.class)
-    ));
-
-    verify(transaction1, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction2, never()).send(anyString(), any(SagaResponse.class));
-
-    verify(compensation1, never()).send(request1.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-  }
-
-  @Test
-  public void failFastIfSagaLogIsDown() throws Exception {
-    EventStore sagaLog = mock(EventStore.class);
-    saga = sagaFactory.createSaga(requestJson, sagaId, sagaLog, sagaDefinition);
-
-    doThrow(RuntimeException.class).when(sagaLog).offer(any(SagaStartedEvent.class));
-
-    saga.run();
-
-    verify(sagaLog).offer(any(SagaStartedEvent.class));
-    verify(transaction1, never()).send(anyString(), any(SagaResponse.class));
-    verify(transaction2, never()).send(anyString(), any(SagaResponse.class));
-
-    verify(compensation1, never()).send(request1.serviceName());
-    verify(compensation2, never()).send(request2.serviceName());
-  }
-
-  private Answer<SagaResponse> withAnswer(Callable<SagaResponse> callable) {
-    return invocationOnMock -> callable.call();
-  }
-
-  private EventEnvelope envelope(SagaEvent event) {
-    return new EventEnvelope(idGenerator.nextId(), event);
-  }
-
-  private SagaRequest request(String requestId,
-      String serviceName,
-      Transaction transaction,
-      Compensation compensation,
-      String... parentIds) {
-
-    return new SagaRequestImpl(requestId, serviceName, Operation.TYPE_REST, transaction, compensation, parentIds);
-  }
-
-  private SagaRequest request(String requestId,
-      String serviceName,
-      Transaction transaction,
-      Compensation compensation,
-      Fallback fallback) {
-
-    return new SagaRequestImpl(requestId, serviceName, Operation.TYPE_REST, transaction, compensation, fallback);
-  }
-
-  private HashSet<String> setOf(String requestId) {
-    return new HashSet<>(singletonList(requestId));
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/actors/CompletionCallbackActorTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/actors/CompletionCallbackActorTest.java
deleted file mode 100644
index 5823a069..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/actors/CompletionCallbackActorTest.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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.core.actors;
-
-import static akka.actor.ActorRef.noSender;
-import static akka.actor.Props.empty;
-import static com.seanyinx.github.unit.scaffolding.Randomness.uniquify;
-import static org.awaitility.Awaitility.await;
-import static org.hamcrest.core.Is.is;
-import static org.hamcrest.core.IsInstanceOf.instanceOf;
-import static org.junit.Assert.assertThat;
-
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.servicecomb.saga.core.NoOpSagaRequest;
-import org.apache.servicecomb.saga.core.actors.messages.AbortMessage;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import org.apache.servicecomb.saga.core.FailedSagaResponse;
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.apache.servicecomb.saga.core.actors.messages.CompensateMessage;
-import org.apache.servicecomb.saga.core.actors.messages.FailMessage;
-import org.apache.servicecomb.saga.core.actors.messages.TransactMessage;
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.testkit.javadsl.TestKit;
-
-public class CompletionCallbackActorTest {
-  private static final ActorSystem actorSystem = ActorSystem.create();
-
-  private final SagaResponse response = Mockito.mock(SagaResponse.class);
-  private final RequestActorContext context = new RequestActorContext(null);
-
-  private final ActorRef actor1 = someActor();
-  private final ActorRef actor2 = someActor();
-
-  @Before
-  public void setUp() throws Exception {
-    context.addActor(uniquify("requestId"), actor1);
-    context.addActor(uniquify("requestId"), actor2);
-  }
-
-  @AfterClass
-  public static void tearDown() throws Exception {
-    TestKit.shutdownActorSystem(actorSystem);
-  }
-
-  @Test
-  public void killAllOnTransactionComplete() throws Exception {
-    new TestKit(actorSystem) {{
-      CompletableFuture<SagaResponse> future = new CompletableFuture<>();
-
-      ActorRef actor = actorSystem.actorOf(CompletionCallbackActor.props(future));
-
-      actor.tell(context, noSender());
-      actor.tell(new TransactMessage(null, response), noSender());
-
-      await().atMost(2, TimeUnit.SECONDS)
-          .until(() -> actor1.isTerminated() && actor2.isTerminated() && actor.isTerminated());
-
-      assertThat(future.get(), is(response));
-    }};
-  }
-
-  @Test
-  public void killAllOnCompensationComplete() throws Exception {
-    new TestKit(actorSystem) {{
-      CompletableFuture<SagaResponse> future = new CompletableFuture<>();
-
-      ActorRef actor = actorSystem.actorOf(CompletionCallbackActor.props(future));
-
-      actor.tell(context, noSender());
-      actor.tell(new CompensateMessage(response), noSender());
-
-      await().atMost(2, TimeUnit.SECONDS)
-          .until(() -> actor1.isTerminated() && actor2.isTerminated() && actor.isTerminated());
-
-      assertThat(future.get(), is(response));
-    }};
-  }
-
-  @Test
-  public void killAllOnFailure() throws Exception {
-    new TestKit(actorSystem) {{
-      CompletableFuture<SagaResponse> future = new CompletableFuture<>();
-
-      ActorRef actor = actorSystem.actorOf(CompletionCallbackActor.props(future));
-
-      actor.tell(context, noSender());
-      actor.tell(new FailMessage(new RuntimeException("oops")), noSender());
-
-      await().atMost(2, TimeUnit.SECONDS)
-          .until(() -> actor1.isTerminated() && actor2.isTerminated() && actor.isTerminated());
-
-      assertThat(future.get(), is(instanceOf(FailedSagaResponse.class)));
-    }};
-  }
-
-  @Test
-  public void tellLeafToCompensateOnAbort() throws Exception {
-    new TestKit(actorSystem) {{
-      context.addActor(NoOpSagaRequest.SAGA_END_REQUEST.id(), getRef());
-      CompletableFuture<SagaResponse> future = new CompletableFuture<>();
-
-      ActorRef actor = actorSystem.actorOf(CompletionCallbackActor.props(future));
-
-      actor.tell(context, noSender());
-      AbortMessage message = new AbortMessage(new RuntimeException("oops"));
-      actor.tell(message, noSender());
-
-      CompensateMessage compensateMessage = (CompensateMessage) receiveOne(duration("2 seconds"));
-      assertThat(compensateMessage.response(), is(message.response()));
-    }};
-  }
-
-  private ActorRef someActor() {
-    return actorSystem.actorOf(empty());
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/actors/EventContextImplTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/actors/EventContextImplTest.java
deleted file mode 100644
index cfd37887..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/actors/EventContextImplTest.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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.core.actors;
-
-import static com.seanyinx.github.unit.scaffolding.Randomness.uniquify;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.when;
-
-import org.apache.servicecomb.saga.core.SagaRequest;
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.apache.servicecomb.saga.core.actors.messages.AbortRecoveryMessage;
-import org.apache.servicecomb.saga.core.actors.messages.CompensationRecoveryMessage;
-import org.apache.servicecomb.saga.core.actors.messages.TransactionRecoveryMessage;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.scalatest.junit.JUnitSuite;
-
-import akka.actor.ActorSystem;
-import akka.testkit.javadsl.TestKit;
-
-public class EventContextImplTest extends JUnitSuite {
-  private static final ActorSystem actorSystem = ActorSystem.create();
-
-  private final SagaRequest request = Mockito.mock(SagaRequest.class);
-  private final SagaResponse response = Mockito.mock(SagaResponse.class);
-
-  private final RequestActorContext context = new RequestActorContext(null);
-  private final EventContextImpl eventContext = new EventContextImpl(context);
-  private final String requestId = uniquify("requestId");
-
-  @Before
-  public void setUp() throws Exception {
-    when(request.id()).thenReturn(requestId);
-  }
-
-  @AfterClass
-  public static void tearDown() throws Exception {
-    TestKit.shutdownActorSystem(actorSystem);
-  }
-
-  @Test
-  public void sendTransactionRecoveryMessageToActor_OnTransactionEnd() throws Exception {
-    new TestKit(actorSystem) {{
-      context.addActor(requestId, getRef());
-
-      eventContext.endTransaction(request, response);
-
-      TransactionRecoveryMessage message = (TransactionRecoveryMessage) receiveOne(duration("2 seconds"));
-      assertThat(message.response(), is(response));
-    }};
-  }
-
-  @Test
-  public void sendCompensationRecoveryMessageToActor_OnCompensationEnd() throws Exception {
-    new TestKit(actorSystem) {{
-      context.addActor(requestId, getRef());
-
-      eventContext.compensateTransaction(request, response);
-
-      expectMsgClass(CompensationRecoveryMessage.class);
-    }};
-  }
-
-  @Test
-  public void sendAbortMessageToActor_OnAbort() throws Exception {
-    new TestKit(actorSystem) {{
-      context.addActor(requestId, getRef());
-
-      eventContext.abortTransaction(request, response);
-
-      AbortRecoveryMessage message = ((AbortRecoveryMessage) receiveOne(duration("2 seconds")));
-      assertThat(message.response(), is(response));
-    }};
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/actors/RequestActorBuilderTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/actors/RequestActorBuilderTest.java
deleted file mode 100644
index b3a2c149..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/actors/RequestActorBuilderTest.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * 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.core.actors;
-
-import static org.hamcrest.Matchers.containsInAnyOrder;
-import static org.hamcrest.core.IsInstanceOf.instanceOf;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import org.apache.servicecomb.saga.core.NoOpSagaRequest;
-import org.apache.servicecomb.saga.core.SagaRequest;
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.apache.servicecomb.saga.core.SagaTask;
-import org.hamcrest.Matchers;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mockito;
-import org.scalatest.junit.JUnitSuite;
-
-import com.seanyinx.github.unit.scaffolding.Randomness;
-
-import org.apache.servicecomb.saga.core.CompositeSagaResponse;
-import org.apache.servicecomb.saga.core.actors.messages.CompensateMessage;
-import org.apache.servicecomb.saga.core.actors.messages.TransactMessage;
-import org.apache.servicecomb.saga.core.application.interpreter.FromJsonFormat;
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.testkit.javadsl.TestKit;
-
-@SuppressWarnings("unchecked")
-public class RequestActorBuilderTest extends JUnitSuite {
-  private static final ActorSystem actorSystem = ActorSystem.create();
-
-  private final String requestId1 = Randomness.uniquify("requestId1");
-  private final String requestId2 = Randomness.uniquify("requestId2");
-  private final String requestId3 = Randomness.uniquify("requestId3");
-  private final String taskId = "some task";
-
-  private final SagaRequest request1 = Mockito.mock(SagaRequest.class);
-  private final SagaRequest request2 = Mockito.mock(SagaRequest.class);
-  private final SagaRequest request3 = Mockito.mock(SagaRequest.class);
-
-  private final SagaResponse response1 = Mockito.mock(SagaResponse.class);
-  private final SagaResponse response2 = Mockito.mock(SagaResponse.class);
-  private final SagaResponse response3 = Mockito.mock(SagaResponse.class);
-
-  private final SagaRequest[] requests = {request1, request2, request3};
-
-  private final SagaTask task = Mockito.mock(SagaTask.class);
-  private final Map<String, SagaTask> tasks = new HashMap<>();
-
-  private final FromJsonFormat<Set<String>> childrenExtractor = Mockito.mock(FromJsonFormat.class);
-  private final RequestActorBuilder actorBuilder = new RequestActorBuilder(actorSystem, childrenExtractor);
-
-  @Before
-  public void setUp() throws Exception {
-    tasks.put(SagaTask.SAGA_START_TASK, task);
-    tasks.put(SagaTask.SAGA_END_TASK, task);
-    tasks.put(taskId, task);
-
-    when(request1.id()).thenReturn(requestId1);
-    when(request2.id()).thenReturn(requestId2);
-    when(request3.id()).thenReturn(requestId3);
-
-    when(request1.task()).thenReturn(taskId);
-    when(request2.task()).thenReturn(taskId);
-    when(request3.task()).thenReturn(taskId);
-
-    when(request1.parents()).thenReturn(new String[0]);
-    when(request2.parents()).thenReturn(new String[] {requestId1});
-    when(request3.parents()).thenReturn(new String[] {requestId1});
-
-    when(task.commit(NoOpSagaRequest.SAGA_START_REQUEST, SagaResponse.EMPTY_RESPONSE)).thenReturn(
-        SagaResponse.EMPTY_RESPONSE);
-    when(task.commit(request1, SagaResponse.EMPTY_RESPONSE)).thenReturn(response1);
-    when(task.commit(request2, response1)).thenReturn(response2);
-    when(task.commit(request3, response1)).thenReturn(response3);
-
-    when(childrenExtractor.fromJson(anyString())).thenReturn(Collections.emptySet());
-  }
-
-  @AfterClass
-  public static void tearDown() throws Exception {
-    TestKit.shutdownActorSystem(actorSystem);
-  }
-
-  @Test
-  public void createOneActorPerRequest() throws Exception {
-    new TestKit(actorSystem) {{
-      ArgumentCaptor<SagaResponse> argumentCaptor = ArgumentCaptor.forClass(SagaResponse.class);
-      when(task.commit(eq(NoOpSagaRequest.SAGA_END_REQUEST), argumentCaptor.capture())).thenReturn(
-          SagaResponse.EMPTY_RESPONSE);
-
-      ActorRef root = actorBuilder.build(requests, tasks, getRef()).actorOf(NoOpSagaRequest.SAGA_START_REQUEST.id());
-
-      root.tell(new TransactMessage(NoOpSagaRequest.SAGA_START_REQUEST, SagaResponse.EMPTY_RESPONSE), getRef());
-
-      List<SagaResponse> responses = receiveN(1, duration("2 seconds")).stream()
-          .map(o -> ((TransactMessage) o).response())
-          .collect(Collectors.toList());
-
-      assertThat(responses, Matchers.containsInAnyOrder(SagaResponse.EMPTY_RESPONSE));
-
-      verify(task).commit(NoOpSagaRequest.SAGA_START_REQUEST, SagaResponse.EMPTY_RESPONSE);
-      verify(task).commit(request1, SagaResponse.EMPTY_RESPONSE);
-      verify(task).commit(request2, response1);
-      verify(task).commit(request3, response1);
-      verify(task).commit(eq(NoOpSagaRequest.SAGA_END_REQUEST), any(SagaResponse.class));
-
-      SagaResponse response = argumentCaptor.getValue();
-      assertThat(response, instanceOf(CompositeSagaResponse.class));
-      assertThat(((CompositeSagaResponse) response).responses(),
-          containsInAnyOrder(response2, response3));
-    }};
-  }
-
-  @Test
-  public void compensateAllCompletedTransactions() throws Exception {
-    new TestKit(actorSystem) {{
-      ArgumentCaptor<SagaResponse> argumentCaptor = ArgumentCaptor.forClass(SagaResponse.class);
-      when(task.commit(eq(NoOpSagaRequest.SAGA_END_REQUEST), argumentCaptor.capture())).thenReturn(
-          SagaResponse.EMPTY_RESPONSE);
-
-      ActorRef root = actorBuilder.build(requests, tasks, getRef()).actorOf(NoOpSagaRequest.SAGA_START_REQUEST.id());
-
-      root.tell(new TransactMessage(NoOpSagaRequest.SAGA_START_REQUEST, SagaResponse.EMPTY_RESPONSE), getRef());
-
-      List<SagaResponse> responses = receiveN(1, duration("2 seconds")).stream()
-          .map(o -> ((TransactMessage) o).response())
-          .collect(Collectors.toList());
-
-      assertThat(responses, Matchers.containsInAnyOrder(SagaResponse.EMPTY_RESPONSE));
-
-      CompensateMessage message = new CompensateMessage(response1);
-      getLastSender().tell(message, getRef());
-      expectMsg(message);
-
-      verify(task).compensate(NoOpSagaRequest.SAGA_START_REQUEST);
-      verify(task).compensate(request1);
-      verify(task).compensate(request2);
-      verify(task).compensate(request3);
-      verify(task).compensate(NoOpSagaRequest.SAGA_END_REQUEST);
-    }};
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/actors/RequestActorTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/actors/RequestActorTest.java
deleted file mode 100644
index 776b5aad..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/actors/RequestActorTest.java
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * 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.core.actors;
-
-import static akka.actor.ActorRef.noSender;
-import static akka.actor.Props.empty;
-import static com.seanyinx.github.unit.scaffolding.Randomness.uniquify;
-import static java.util.Collections.emptySet;
-import static java.util.Collections.singleton;
-import static org.hamcrest.Matchers.contains;
-import static org.hamcrest.Matchers.containsInAnyOrder;
-import static org.hamcrest.core.IsInstanceOf.instanceOf;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import org.apache.servicecomb.saga.core.CompositeSagaResponse;
-import org.apache.servicecomb.saga.core.FailedSagaResponse;
-import org.apache.servicecomb.saga.core.Operation;
-import org.apache.servicecomb.saga.core.SagaRequest;
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.apache.servicecomb.saga.core.SagaStartFailedException;
-import org.apache.servicecomb.saga.core.SagaTask;
-import org.apache.servicecomb.saga.core.TransactionFailedException;
-import org.apache.servicecomb.saga.core.actors.messages.AbortMessage;
-import org.apache.servicecomb.saga.core.actors.messages.CompensationRecoveryMessage;
-import org.apache.servicecomb.saga.core.actors.messages.TransactMessage;
-import org.apache.servicecomb.saga.core.actors.messages.TransactionRecoveryMessage;
-import org.hamcrest.Matchers;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mockito;
-import org.scalatest.junit.JUnitSuite;
-
-import org.apache.servicecomb.saga.core.actors.messages.CompensateMessage;
-import org.apache.servicecomb.saga.core.actors.messages.FailMessage;
-import org.apache.servicecomb.saga.core.application.interpreter.FromJsonFormat;
-import akka.actor.ActorRef;
-import akka.actor.ActorSystem;
-import akka.testkit.javadsl.TestKit;
-
-@SuppressWarnings("unchecked")
-public class RequestActorTest extends JUnitSuite {
-  private final String parentRequestId1 = uniquify("parentRequestId1");
-  private final String parentRequestId2 = uniquify("parentRequestId2");
-  private final String requestId = uniquify("requestId");
-
-  private final SagaTask task = Mockito.mock(SagaTask.class);
-  private final SagaRequest request = Mockito.mock(SagaRequest.class, "request");
-  private final SagaRequest request1 = Mockito.mock(SagaRequest.class, "request1");
-  private final SagaRequest request2 = Mockito.mock(SagaRequest.class, "request2");
-  private final SagaResponse response = Mockito.mock(SagaResponse.class);
-  private final FromJsonFormat<Set<String>> childrenExtractor = mock(FromJsonFormat.class);
-
-  private final RequestActorContext context = new RequestActorContext(childrenExtractor);
-
-  private final TransactionFailedException exception = new TransactionFailedException("oops");
-  private static final ActorSystem actorSystem = ActorSystem.create();
-  private final CompensateMessage compensateMessage = new CompensateMessage(new FailedSagaResponse(exception));
-
-  @Before
-  public void setUp() throws Exception {
-    when(childrenExtractor.fromJson(anyString())).thenReturn(emptySet());
-    when(request.id()).thenReturn(requestId);
-
-    when(request1.id()).thenReturn(parentRequestId1);
-    when(request2.id()).thenReturn(parentRequestId2);
-  }
-
-  @AfterClass
-  public static void tearDown() throws Exception {
-    TestKit.shutdownActorSystem(actorSystem);
-  }
-
-  @Test
-  public void tellNodeResponseToAllChildren() throws Exception {
-    new TestKit(actorSystem) {{
-      addChildren(getRef());
-
-      ActorRef parent = someActor();
-      context.addParent(requestId, parent);
-
-      when(request.parents()).thenReturn(new String[] {parentRequestId1});
-      when(task.commit(request, Operation.SUCCESSFUL_SAGA_RESPONSE)).thenReturn(response);
-
-      ActorRef actorRef = actorSystem.actorOf(RequestActor.props(context, task, request));
-
-      actorRef.tell(new TransactMessage(request1, Operation.SUCCESSFUL_SAGA_RESPONSE), parent);
-
-      List<SagaResponse> responses = receiveN(2, duration("2 seconds")).stream()
-          .map(o -> ((TransactMessage) o).response())
-          .collect(Collectors.toList());
-
-      assertThat(responses, containsInAnyOrder(response, response));
-
-      verify(task).commit(request, Operation.SUCCESSFUL_SAGA_RESPONSE);
-    }};
-  }
-
-  @Test
-  public void executeTransaction_OnlyWhenAllParentsResponsesAreReceived() throws Exception {
-    new TestKit(actorSystem) {{
-      addChildren(getRef());
-
-      ActorRef parent1 = someActor();
-      context.addParent(requestId, parent1);
-
-      ActorRef parent2 = someActor();
-      context.addParent(requestId, parent2);
-
-      ArgumentCaptor<SagaResponse> argumentCaptor = ArgumentCaptor.forClass(SagaResponse.class);
-
-      when(request.parents()).thenReturn(new String[] {parentRequestId1, parentRequestId2});
-      when(task.commit(eq(request), argumentCaptor.capture())).thenReturn(response);
-
-      ActorRef actorRef = actorSystem.actorOf(RequestActor.props(context, task, request));
-
-      actorRef.tell(new TransactMessage(request1, Operation.SUCCESSFUL_SAGA_RESPONSE), parent1);
-      expectNoMsg(duration("500 milliseconds"));
-
-      actorRef.tell(new TransactMessage(request2, SagaResponse.EMPTY_RESPONSE), parent2);
-
-      List<SagaResponse> responses = receiveN(2, duration("2 seconds")).stream()
-          .map(o -> ((TransactMessage) o).response())
-          .collect(Collectors.toList());
-
-      assertThat(responses, containsInAnyOrder(response, response));
-
-      SagaResponse response = argumentCaptor.getValue();
-      assertThat(response, instanceOf(CompositeSagaResponse.class));
-      assertThat(((CompositeSagaResponse) response).responses(),
-          Matchers.containsInAnyOrder(SagaResponse.EMPTY_RESPONSE, Operation.SUCCESSFUL_SAGA_RESPONSE));
-    }};
-  }
-
-  @Test
-  public void tellAllRelativesToAbortOnError() throws Exception {
-    new TestKit(actorSystem) {{
-      context.addChild(requestId, getRef());
-      context.addActor(requestId, getRef());
-
-      context.addParent(requestId, getRef());
-
-      when(request.parents()).thenReturn(new String[] {parentRequestId1});
-      when(task.commit(request, Operation.SUCCESSFUL_SAGA_RESPONSE)).thenThrow(exception);
-
-      ActorRef actorRef = actorSystem.actorOf(RequestActor.props(context, task, request));
-
-      actorRef.tell(new TransactMessage(request1, Operation.SUCCESSFUL_SAGA_RESPONSE), getRef());
-
-      List<SagaResponse> responses = receiveN(2, duration("2 seconds")).stream()
-          .map(o -> ((AbortMessage) o).response())
-          .collect(Collectors.toList());
-
-      assertThat(responses, containsInAnyOrder(instanceOf(FailedSagaResponse.class), instanceOf(FailedSagaResponse.class)));
-    }};
-  }
-
-  @Test
-  public void tellAllRelativesExceptSenderToAbortOnAbort() throws Exception {
-    new TestKit(actorSystem) {{
-      context.addChild(requestId, getRef());
-      context.addActor(requestId, getRef());
-
-      context.addParent(requestId, getRef());
-
-      when(request.parents()).thenReturn(new String[] {parentRequestId1});
-
-      ActorRef actorRef = actorSystem.actorOf(RequestActor.props(context, task, request));
-
-      actorRef.tell(new AbortMessage(exception), someActor());
-
-      List<SagaResponse> responses = receiveN(2, duration("2 seconds")).stream()
-          .map(o -> ((AbortMessage) o).response())
-          .collect(Collectors.toList());
-
-      assertThat(responses, containsInAnyOrder(instanceOf(FailedSagaResponse.class), instanceOf(FailedSagaResponse.class)));
-
-      actorRef.tell(new AbortMessage(exception), someActor());
-      expectNoMsg(duration("500 milliseconds"));
-    }};
-  }
-
-  @Test
-  public void compensateIfTransactionIsCompleted() throws Exception {
-    new TestKit(actorSystem) {{
-      addChildren(someActor());
-      context.addParent(requestId, getRef());
-
-      when(request.parents()).thenReturn(new String[] {parentRequestId1});
-      when(task.commit(request, Operation.SUCCESSFUL_SAGA_RESPONSE)).thenReturn(response);
-
-      ActorRef actorRef = actorSystem.actorOf(RequestActor.props(context, task, request));
-
-      actorRef.tell(new TransactMessage(request1, Operation.SUCCESSFUL_SAGA_RESPONSE), getRef());
-      actorRef.tell(new AbortMessage(exception), noSender());
-      actorRef.tell(compensateMessage, getRef());
-      actorRef.tell(compensateMessage, getRef());
-
-      expectMsg(duration("2 seconds"), compensateMessage);
-      verify(task).compensate(request);
-
-      // no duplicate compensation
-      reset(task);
-      actorRef.tell(compensateMessage, getRef());
-      actorRef.tell(compensateMessage, getRef());
-      expectNoMsg(duration("200 milliseconds"));
-      verify(task, never()).compensate(request);
-    }};
-  }
-
-  @Test
-  public void doNotCompensateIfTransactionIsNotCompleted() throws Exception {
-    new TestKit(actorSystem) {{
-      addChildren(someActor());
-      context.addParent(requestId, getRef());
-
-      when(request.parents()).thenReturn(new String[] {parentRequestId1});
-
-      ActorRef actorRef = actorSystem.actorOf(RequestActor.props(context, task, request));
-
-      actorRef.tell(new AbortMessage(exception), noSender());
-      actorRef.tell(compensateMessage, getRef());
-      actorRef.tell(compensateMessage, getRef());
-
-      List<Object> responses = receiveN(2, duration("2 seconds"));
-      assertThat(responses, contains(instanceOf(AbortMessage.class), instanceOf(CompensateMessage.class)));
-      verify(task, never()).compensate(request);
-
-      // no duplicate compensation
-      reset(task);
-      actorRef.tell(compensateMessage, getRef());
-      actorRef.tell(compensateMessage, getRef());
-      expectNoMsg(duration("200 milliseconds"));
-      verify(task, never()).compensate(request);
-    }};
-  }
-
-  @Test
-  public void skipIfActorIsNotChosenByAnyParent() throws Exception {
-    when(childrenExtractor.fromJson(Operation.SUCCESSFUL_SAGA_RESPONSE.body())).thenReturn(singleton("none"));
-
-    new TestKit(actorSystem) {{
-      addChildren(getRef());
-      context.addParent(requestId, getRef());
-
-      when(request.parents()).thenReturn(new String[] {parentRequestId1});
-
-      ActorRef actorRef = actorSystem.actorOf(RequestActor.props(context, task, request));
-
-      actorRef.tell(new TransactMessage(request1, Operation.SUCCESSFUL_SAGA_RESPONSE), getRef());
-
-      List<SagaResponse> responses = receiveN(2, duration("2 seconds")).stream()
-          .map(o -> ((TransactMessage) o).response())
-          .collect(Collectors.toList());
-
-      assertThat(responses, Matchers.containsInAnyOrder(SagaResponse.NONE_RESPONSE, SagaResponse.NONE_RESPONSE));
-      verify(task, never()).commit(request, Operation.SUCCESSFUL_SAGA_RESPONSE);
-
-      // skip compensation for ignored actor
-      actorRef.tell(compensateMessage, getRef());
-      actorRef.tell(compensateMessage, getRef());
-
-      expectMsg(duration("2 seconds"), compensateMessage);
-      verify(task, never()).compensate(request);
-    }};
-  }
-
-  @Test
-  public void transactIfChosenByAnyParent() throws Exception {
-    when(childrenExtractor.fromJson(Operation.SUCCESSFUL_SAGA_RESPONSE.body())).thenReturn(singleton(requestId));
-
-    new TestKit(actorSystem) {{
-      addChildren(getRef());
-
-      ActorRef parent1 = someActor();
-      context.addParent(requestId, parent1);
-
-      ActorRef parent2 = someActor();
-      context.addParent(requestId, parent2);
-
-      when(request.parents()).thenReturn(new String[] {parentRequestId1, parentRequestId2});
-      when(task.commit(eq(request), any(CompositeSagaResponse.class))).thenReturn(response);
-
-      ActorRef actorRef = actorSystem.actorOf(RequestActor.props(context, task, request));
-
-      actorRef.tell(new TransactMessage(request1, Operation.SUCCESSFUL_SAGA_RESPONSE), parent1);
-      actorRef.tell(new TransactMessage(request2, Operation.SUCCESSFUL_SAGA_RESPONSE), parent2);
-
-      List<SagaResponse> responses = receiveN(2, duration("2 seconds")).stream()
-          .map(o -> ((TransactMessage) o).response())
-          .collect(Collectors.toList());
-
-      assertThat(responses, containsInAnyOrder(response, response));
-    }};
-  }
-
-  @Test
-  public void tellTransactionResponseToChildrenOnRecovery() throws Exception {
-    new TestKit(actorSystem) {{
-      context.addChild(requestId, getRef());
-
-      ActorRef parent = someActor();
-      context.addParent(requestId, parent);
-
-      when(request.parents()).thenReturn(new String[] {parentRequestId1});
-
-      ActorRef actorRef = actorSystem.actorOf(RequestActor.props(context, task, request));
-
-      actorRef.tell(new TransactionRecoveryMessage(response), noSender());
-      actorRef.tell(new TransactMessage(request1, Operation.SUCCESSFUL_SAGA_RESPONSE), parent);
-
-      List<SagaResponse> responses = receiveN(1, duration("2 seconds")).stream()
-          .map(o -> ((TransactMessage) o).response())
-          .collect(Collectors.toList());
-
-      assertThat(responses, containsInAnyOrder(response));
-
-      verify(task, never()).commit(request, Operation.SUCCESSFUL_SAGA_RESPONSE);
-    }};
-  }
-
-  @Test
-  public void tellCompensationToParentsOnRecovery() throws Exception {
-    new TestKit(actorSystem) {{
-      context.addChild(requestId, someActor());
-      context.addParent(requestId, getRef());
-
-      when(request.parents()).thenReturn(new String[] {parentRequestId1});
-
-      ActorRef actorRef = actorSystem.actorOf(RequestActor.props(context, task, request));
-
-      actorRef.tell(new AbortMessage(exception), someActor());
-      actorRef.tell(new CompensationRecoveryMessage(), someActor());
-      actorRef.tell(compensateMessage, someActor());
-
-      List<Object> responses = receiveN(2, duration("2 seconds"));
-      assertThat(responses, contains(instanceOf(AbortMessage.class), instanceOf(CompensateMessage.class)));
-
-      verify(task, never()).compensate(request);
-    }};
-  }
-
-  @Test
-  public void abortOnPersistenceFailure() throws Exception {
-    new TestKit(actorSystem) {{
-      context.addChild(requestId, noSender());
-      context.addParent(requestId, getRef());
-
-      when(request.parents()).thenReturn(new String[] {parentRequestId1});
-
-      SagaStartFailedException oops = new SagaStartFailedException("oops", exception);
-      when(task.commit(request, SagaResponse.EMPTY_RESPONSE)).thenThrow(oops);
-
-      ActorRef actorRef = actorSystem.actorOf(RequestActor.props(context, task, request));
-
-      actorRef.tell(new TransactMessage(request, SagaResponse.EMPTY_RESPONSE), getRef());
-
-      expectMsgClass(FailMessage.class);
-    }};
-  }
-
-  private ActorRef someActor() {
-    return actorSystem.actorOf(empty());
-  }
-
-  private void addChildren(ActorRef ref) {
-    context.addChild(requestId, ref);
-    context.addChild(requestId, ref);
-    context.addActor(requestId, ref);
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/dag/DirectedAcyclicGraphTraversalTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/dag/DirectedAcyclicGraphTraversalTest.java
deleted file mode 100644
index beb96076..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/dag/DirectedAcyclicGraphTraversalTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * 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.core.dag;
-
-import static java.util.Arrays.asList;
-import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
-import static org.junit.Assert.assertThat;
-
-import java.util.Collection;
-import org.junit.Before;
-import org.junit.Test;
-
-public class DirectedAcyclicGraphTraversalTest {
-
-  private final Node<String> root = new Node<>(0, "i don't care");
-  private final Node<String> node1 = new Node<>(1, "i don't care");
-  private final Node<String> node2 = new Node<>(2, "i don't care");
-  private final Node<String> node3 = new Node<>(3, "i don't care");
-  private final Node<String> node4 = new Node<>(4, "i don't care");
-  private final Node<String> node5 = new Node<>(5, "i don't care");
-  private final Node<String> leaf = new Node<>(6, "i don't care");
-
-  private final SingleLeafDirectedAcyclicGraph<String> dag = new SingleLeafDirectedAcyclicGraph<>(root, leaf);
-
-  //        0
-  //       / \
-  //      1   \
-  //     / \   \
-  //    3   4   2
-  //     \ /   /
-  //      5   /
-  //       \ /
-  //        6
-  @Before
-  public void setUp() throws Exception {
-    root.addChildren(asList(node1, node2));
-    node1.addChildren(asList(node3, node4));
-    node3.addChild(node5);
-    node4.addChild(node5);
-    node5.addChild(leaf);
-    node2.addChild(leaf);
-  }
-
-  @Test
-  public void traverseGraphOneLevelPerStepFromRoot() {
-    Traveller<String> traveller = new ByLevelTraveller<>(dag, new FromRootTraversalDirection<>());
-
-    Collection<Node<String>> nodes = traveller.nodes();
-
-    traveller.next();
-    assertThat(nodes, contains(root));
-
-    traveller.next();
-    assertThat(nodes, contains(root, node1, node2));
-
-    traveller.next();
-    assertThat(nodes, contains(root, node1, node2, node3, node4));
-
-    traveller.next();
-    assertThat(nodes, contains(root, node1, node2, node3, node4, node5));
-
-    traveller.next();
-    assertThat(nodes, contains(root, node1, node2, node3, node4, node5, leaf));
-  }
-
-  @Test
-  public void traverseGraphOneLevelPerStepFromLeaf() {
-    Traveller<String> traveller = new ByLevelTraveller<>(dag, new FromLeafTraversalDirection<>());
-
-    Collection<Node<String>> nodes = traveller.nodes();
-
-    traveller.next();
-    assertThat(nodes, contains(leaf));
-
-    traveller.next();
-    assertThat(nodes, contains(leaf, node2, node5));
-
-    traveller.next();
-    assertThat(nodes, contains(leaf, node2, node5, node3, node4));
-
-    traveller.next();
-    assertThat(nodes, contains(leaf, node2, node5, node3, node4, node1));
-
-    traveller.next();
-    assertThat(nodes, contains(leaf, node2, node5, node3, node4, node1, root));
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/dag/GraphBasedSagaExecutionComponentTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/dag/GraphBasedSagaExecutionComponentTest.java
deleted file mode 100644
index 8515f93d..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/dag/GraphBasedSagaExecutionComponentTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.core.dag;
-
-import java.util.concurrent.Executors;
-
-import org.apache.servicecomb.saga.core.PersistentStore;
-import org.apache.servicecomb.saga.core.SagaExecutionComponentTestBase;
-import org.apache.servicecomb.saga.core.application.SagaFactory;
-
-
-public class GraphBasedSagaExecutionComponentTest extends SagaExecutionComponentTestBase {
-
-  @Override
-  protected SagaFactory sagaFactory(PersistentStore eventStore) {
-    return new GraphBasedSagaFactory(500, eventStore, null, Executors.newFixedThreadPool(5));
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/dag/GraphBuilderTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/dag/GraphBuilderTest.java
deleted file mode 100644
index 8703c7a2..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/dag/GraphBuilderTest.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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.core.dag;
-
-import static com.seanyinx.github.unit.scaffolding.AssertUtils.expectFailing;
-import static org.apache.servicecomb.saga.core.Operation.TYPE_REST;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.emptySet;
-import static java.util.Collections.singleton;
-import static org.hamcrest.CoreMatchers.startsWith;
-import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.when;
-
-import java.util.Collection;
-import java.util.stream.Collectors;
-
-import org.apache.servicecomb.saga.core.NoOpSagaRequest;
-import org.apache.servicecomb.saga.core.SagaException;
-import org.apache.servicecomb.saga.core.SagaRequest;
-import org.apache.servicecomb.saga.core.SagaRequestImpl;
-import org.hamcrest.collection.IsIterableContainingInOrder;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import org.apache.servicecomb.saga.core.CompensationImpl;
-import org.apache.servicecomb.saga.core.TransactionImpl;
-
-@SuppressWarnings("unchecked")
-public class GraphBuilderTest {
-
-  private final SagaRequest request1 = new SagaRequestImpl(
-      "request-aaa",
-      "aaa",
-      TYPE_REST,
-      new TransactionImpl("/rest/as", "post", emptyMap()),
-      new CompensationImpl("/rest/as","delete", emptyMap())
-  );
-
-  private final SagaRequest request2 = new SagaRequestImpl(
-      "request-bbb",
-      "bbb",
-      TYPE_REST,
-      new TransactionImpl("/rest/bs", "post", emptyMap()),
-      new CompensationImpl("/rest/bs","delete", emptyMap())
-  );
-
-  private final SagaRequest request3 = new SagaRequestImpl(
-      "request-ccc",
-      "ccc",
-      TYPE_REST,
-      new TransactionImpl("/rest/cs", "post", emptyMap()),
-      new CompensationImpl("/rest/cs","delete", emptyMap()),
-      null,
-      new String[]{"request-aaa", "request-bbb"}
-  );
-  private final SagaRequest[] requests = {request1, request2, request3};
-
-  private final SagaRequest duplicateRequest = new SagaRequestImpl(
-      "request-duplicate-id",
-      "xxx",
-      TYPE_REST,
-      new TransactionImpl("/rest/xs", "post", emptyMap()),
-      new CompensationImpl("/rest/xs","delete", emptyMap())
-  );
-  private final SagaRequest[] duplicateRequests = {duplicateRequest, duplicateRequest};
-
-  private final GraphCycleDetector<SagaRequest> detector = Mockito.mock(GraphCycleDetector.class);
-  private final GraphBuilder graphBuilder = new GraphBuilder(detector);
-
-  @Before
-  public void setUp() throws Exception {
-    when(detector.cycleJoints(any())).thenReturn(emptySet());
-  }
-
-  @Test
-  public void buildsGraphOfParallelRequests() {
-    SingleLeafDirectedAcyclicGraph<SagaRequest> tasks = graphBuilder.build(requests);
-
-    Traveller<SagaRequest> traveller = new ByLevelTraveller<>(tasks, new FromRootTraversalDirection<>());
-    Collection<Node<SagaRequest>> nodes = traveller.nodes();
-
-    traveller.next();
-    assertThat(requestsOf(nodes), IsIterableContainingInOrder.contains(NoOpSagaRequest.SAGA_START_REQUEST));
-    nodes.clear();
-
-    traveller.next();
-    assertThat(requestsOf(nodes), contains(request1, request2));
-    nodes.clear();
-
-    traveller.next();
-    assertThat(requestsOf(nodes), contains(request3));
-    nodes.clear();
-
-    traveller.next();
-    assertThat(requestsOf(nodes), IsIterableContainingInOrder.contains(NoOpSagaRequest.SAGA_END_REQUEST));
-  }
-
-  @Test
-  public void blowsUpWhenJsonContainsDuplicateRequestId() {
-    try {
-      graphBuilder.build(duplicateRequests);
-      fail(SagaException.class.getSimpleName() + " is expected, but none thrown");
-    } catch (SagaException e) {
-      assertThat(e.getMessage(),
-          is("Failed to interpret requests with duplicate request id: request-duplicate-id"));
-    }
-  }
-
-  @Test
-  public void blowsUpWhenGraphContainsCycle() {
-    reset(detector);
-    when(detector.cycleJoints(any())).thenReturn(singleton(new Node<>(0L, null)));
-
-    try {
-      graphBuilder.build(requests);
-      expectFailing(SagaException.class);
-    } catch (SagaException e) {
-      assertThat(e.getMessage(), startsWith("Cycle detected in the request graph at nodes "));
-    }
-  }
-
-  private Collection<SagaRequest> requestsOf(Collection<Node<SagaRequest>> nodes) {
-    return nodes.stream()
-        .map(Node::value)
-        .collect(Collectors.toList());
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/dag/GraphCycleDetectorTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/dag/GraphCycleDetectorTest.java
deleted file mode 100644
index 934c54b6..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/dag/GraphCycleDetectorTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.core.dag;
-
-import static org.hamcrest.Matchers.contains;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-
-import java.util.Set;
-import org.junit.Before;
-import org.junit.Test;
-
-@SuppressWarnings("unchecked")
-public class GraphCycleDetectorTest {
-
-  private final Node<String> root = node(0);
-  private final Node<String> leaf = node(Long.MAX_VALUE);
-
-  private final Node<String> node1 = node(1);
-  private final Node<String> node2 = node(2);
-  private final Node<String> node3 = node(3);
-
-  private final SingleLeafDirectedAcyclicGraph<String> graph = new SingleLeafDirectedAcyclicGraph<>(root, leaf);
-  private final GraphCycleDetector<String> detector = new GraphCycleDetectorImpl<>();
-
-  @Before
-  public void setUp() throws Exception {
-    root.addChild(node1);
-
-    node2.addChild(leaf);
-    node3.addChild(leaf);
-  }
-
-  @Test
-  public void emptyNodesWhenNoCycleInGraph() {
-    node1.addChild(node2);
-    node1.addChild(node3);
-
-    Set<Node<String>> nodes = detector.cycleJoints(graph);
-
-    assertThat(nodes.isEmpty(), is(true));
-  }
-
-  @Test
-  public void nonEmptyNodesIfGraphContainsCycle() {
-    node1.addChild(node2);
-    node2.addChild(node3);
-    node3.addChild(node1);
-
-    Set<Node<String>> nodes = detector.cycleJoints(graph);
-
-    assertThat(nodes, contains(node1));
-  }
-
-  private Node<String> node(long id) {
-    return new Node<>(id, "value " + id);
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/core/dag/NodeTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/core/dag/NodeTest.java
deleted file mode 100644
index 2da4ba0b..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/core/dag/NodeTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.core.dag;
-
-import static java.util.Arrays.asList;
-import static org.hamcrest.Matchers.containsInAnyOrder;
-import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class NodeTest {
-
-
-  private final Node<String> parent = new Node<>(0, "i don't care");
-  private final Node<String> node1 = new Node<>(1, "i don't care");
-  private final Node<String> node2 = new Node<>(2, "i don't care");
-  private final Node<String> node3 = new Node<>(3, "i don't care");
-  private final Node<String> node4 = new Node<>(4, "i don't care");
-  private final Node<String> node5 = new Node<>(5, "i don't care");
-  private final Node<String> node6 = new Node<>(6, "i don't care");
-
-  //        0
-  //       / \
-  //      1   \
-  //     / \   \
-  //    3   4   2
-  //     \ /   /
-  //      5   /
-  //       \ /
-  //        6
-  @Before
-  public void setUp() throws Exception {
-    parent.addChildren(asList(node1, node2));
-    node1.addChildren(asList(node3, node4));
-    node3.addChild(node5);
-    node4.addChild(node5);
-    node5.addChild(node6);
-    node2.addChild(node6);
-  }
-
-  @Test
-  public void nodeIsLinkedBidirectionally() {
-    assertThat(parent.children(), containsInAnyOrder(node1, node2));
-    assertThat(node1.parents(), contains(parent));
-    assertThat(node1.children(), containsInAnyOrder(node3, node4));
-
-    assertThat(node2.parents(), contains(parent));
-    assertThat(node2.children(), contains(node6));
-
-    assertThat(node3.parents(), contains(node1));
-    assertThat(node3.children(), contains(node5));
-
-    assertThat(node4.parents(), contains(node1));
-    assertThat(node4.children(), contains(node5));
-
-    assertThat(node5.parents(), containsInAnyOrder(node3, node4));
-    assertThat(node5.children(), contains(node6));
-
-    assertThat(node6.parents(), containsInAnyOrder(node2, node5));
-    assertThat(node6.children().isEmpty(), is(true));
-  }
-}
diff --git a/saga-core/src/test/java/org/apache/servicecomb/saga/infrastructure/ContextAwareEventStoreTest.java b/saga-core/src/test/java/org/apache/servicecomb/saga/infrastructure/ContextAwareEventStoreTest.java
deleted file mode 100644
index 1216e5f1..00000000
--- a/saga-core/src/test/java/org/apache/servicecomb/saga/infrastructure/ContextAwareEventStoreTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.infrastructure;
-
-import static org.mockito.Mockito.verify;
-
-import org.apache.servicecomb.saga.core.EventStore;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import org.apache.servicecomb.saga.core.SagaContext;
-import org.apache.servicecomb.saga.core.SagaEvent;
-
-public class ContextAwareEventStoreTest {
-  private final EventStore underlying = Mockito.mock(EventStore.class);
-  private final SagaContext context = Mockito.mock(SagaContext.class);
-  private final SagaEvent sagaEvent = Mockito.mock(SagaEvent.class);
-
-  private final ContextAwareEventStore contextAwareEventStore = new ContextAwareEventStore(underlying, context);
-
-  @Test
-  public void persistWithUnderlyingStore() throws Exception {
-    contextAwareEventStore.offer(sagaEvent);
-
-    verify(sagaEvent).gatherTo(context);
-    verify(underlying).offer(sagaEvent);
-  }
-}
diff --git a/saga-core/src/test/resources/application.conf b/saga-core/src/test/resources/application.conf
deleted file mode 100644
index 0629dd63..00000000
--- a/saga-core/src/test/resources/application.conf
+++ /dev/null
@@ -1,21 +0,0 @@
-## ---------------------------------------------------------------------------
-## 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.
-## ---------------------------------------------------------------------------
-akka {
-  loggers = ["akka.event.slf4j.Slf4jLogger"]
-  loglevel = "DEBUG"
-  logging-filter = "akka.event.slf4j.Slf4jLoggingFilter"
-}
diff --git a/saga-core/src/test/resources/log4j2.xml b/saga-core/src/test/resources/log4j2.xml
deleted file mode 100644
index cae04cb9..00000000
--- a/saga-core/src/test/resources/log4j2.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?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/pack-demo/README.md b/saga-demo/booking/README.md
similarity index 100%
rename from saga-demo/pack-demo/README.md
rename to saga-demo/booking/README.md
diff --git a/saga-demo/pack-demo/booking/pom.xml b/saga-demo/booking/booking/pom.xml
similarity index 98%
rename from saga-demo/pack-demo/booking/pom.xml
rename to saga-demo/booking/booking/pom.xml
index 1f88668c..8d75deb4 100644
--- a/saga-demo/pack-demo/booking/pom.xml
+++ b/saga-demo/booking/booking/pom.xml
@@ -18,7 +18,7 @@
 
 <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>
+    <artifactId>booking</artifactId>
     <groupId>org.apache.servicecomb.saga.demo</groupId>
     <version>0.0.3-SNAPSHOT</version>
   </parent>
diff --git a/saga-demo/pack-demo/booking/src/main/java/org/apache/servicecomb/saga/demo/pack/booking/Application.java b/saga-demo/booking/booking/src/main/java/org/apache/servicecomb/saga/demo/pack/booking/Application.java
similarity index 100%
rename from saga-demo/pack-demo/booking/src/main/java/org/apache/servicecomb/saga/demo/pack/booking/Application.java
rename to saga-demo/booking/booking/src/main/java/org/apache/servicecomb/saga/demo/pack/booking/Application.java
diff --git a/saga-demo/pack-demo/booking/src/main/java/org/apache/servicecomb/saga/demo/pack/booking/BookingController.java b/saga-demo/booking/booking/src/main/java/org/apache/servicecomb/saga/demo/pack/booking/BookingController.java
similarity index 100%
rename from saga-demo/pack-demo/booking/src/main/java/org/apache/servicecomb/saga/demo/pack/booking/BookingController.java
rename to saga-demo/booking/booking/src/main/java/org/apache/servicecomb/saga/demo/pack/booking/BookingController.java
diff --git a/saga-demo/pack-demo/booking/src/main/resources/application.yaml b/saga-demo/booking/booking/src/main/resources/application.yaml
similarity index 100%
rename from saga-demo/pack-demo/booking/src/main/resources/application.yaml
rename to saga-demo/booking/booking/src/main/resources/application.yaml
diff --git a/saga-demo/pack-demo/car/pom.xml b/saga-demo/booking/car/pom.xml
similarity index 98%
rename from saga-demo/pack-demo/car/pom.xml
rename to saga-demo/booking/car/pom.xml
index 78ebd5fe..667dc8de 100644
--- a/saga-demo/pack-demo/car/pom.xml
+++ b/saga-demo/booking/car/pom.xml
@@ -18,7 +18,7 @@
 
 <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>
+    <artifactId>booking</artifactId>
     <groupId>org.apache.servicecomb.saga.demo</groupId>
     <version>0.0.3-SNAPSHOT</version>
   </parent>
diff --git a/saga-demo/pack-demo/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/Application.java b/saga-demo/booking/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/Application.java
similarity index 100%
rename from saga-demo/pack-demo/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/Application.java
rename to saga-demo/booking/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/Application.java
diff --git a/saga-demo/pack-demo/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/CarBooking.java b/saga-demo/booking/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/CarBooking.java
similarity index 100%
rename from saga-demo/pack-demo/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/CarBooking.java
rename to saga-demo/booking/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/CarBooking.java
diff --git a/saga-demo/pack-demo/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/CarBookingController.java b/saga-demo/booking/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/CarBookingController.java
similarity index 100%
rename from saga-demo/pack-demo/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/CarBookingController.java
rename to saga-demo/booking/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/CarBookingController.java
diff --git a/saga-demo/pack-demo/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/CarBookingService.java b/saga-demo/booking/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/CarBookingService.java
similarity index 100%
rename from saga-demo/pack-demo/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/CarBookingService.java
rename to saga-demo/booking/car/src/main/java/org/apache/servicecomb/saga/demo/pack/car/CarBookingService.java
diff --git a/saga-demo/pack-demo/car/src/main/resources/application.yaml b/saga-demo/booking/car/src/main/resources/application.yaml
similarity index 100%
rename from saga-demo/pack-demo/car/src/main/resources/application.yaml
rename to saga-demo/booking/car/src/main/resources/application.yaml
diff --git a/saga-demo/pack-demo/docker-compose.mysql.yaml b/saga-demo/booking/docker-compose.mysql.yaml
similarity index 100%
rename from saga-demo/pack-demo/docker-compose.mysql.yaml
rename to saga-demo/booking/docker-compose.mysql.yaml
diff --git a/saga-demo/pack-demo/docker-compose.yaml b/saga-demo/booking/docker-compose.yaml
similarity index 100%
rename from saga-demo/pack-demo/docker-compose.yaml
rename to saga-demo/booking/docker-compose.yaml
diff --git a/saga-demo/pack-demo/hotel/pom.xml b/saga-demo/booking/hotel/pom.xml
similarity index 98%
rename from saga-demo/pack-demo/hotel/pom.xml
rename to saga-demo/booking/hotel/pom.xml
index 8b4dc09c..234d4db6 100644
--- a/saga-demo/pack-demo/hotel/pom.xml
+++ b/saga-demo/booking/hotel/pom.xml
@@ -18,7 +18,7 @@
 
 <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>
+    <artifactId>booking</artifactId>
     <groupId>org.apache.servicecomb.saga.demo</groupId>
     <version>0.0.3-SNAPSHOT</version>
   </parent>
diff --git a/saga-demo/pack-demo/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/Application.java b/saga-demo/booking/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/Application.java
similarity index 100%
rename from saga-demo/pack-demo/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/Application.java
rename to saga-demo/booking/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/Application.java
diff --git a/saga-demo/pack-demo/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/HotelBooking.java b/saga-demo/booking/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/HotelBooking.java
similarity index 100%
rename from saga-demo/pack-demo/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/HotelBooking.java
rename to saga-demo/booking/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/HotelBooking.java
diff --git a/saga-demo/pack-demo/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/HotelBookingController.java b/saga-demo/booking/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/HotelBookingController.java
similarity index 100%
rename from saga-demo/pack-demo/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/HotelBookingController.java
rename to saga-demo/booking/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/HotelBookingController.java
diff --git a/saga-demo/pack-demo/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/HotelBookingService.java b/saga-demo/booking/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/HotelBookingService.java
similarity index 100%
rename from saga-demo/pack-demo/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/HotelBookingService.java
rename to saga-demo/booking/hotel/src/main/java/org/apache/servicecomb/saga/demo/pack/hotel/HotelBookingService.java
diff --git a/saga-demo/pack-demo/hotel/src/main/resources/application.yaml b/saga-demo/booking/hotel/src/main/resources/application.yaml
similarity index 100%
rename from saga-demo/pack-demo/hotel/src/main/resources/application.yaml
rename to saga-demo/booking/hotel/src/main/resources/application.yaml
diff --git a/saga-demo/pack-demo/pom.xml b/saga-demo/booking/pom.xml
similarity index 95%
rename from saga-demo/pack-demo/pom.xml
rename to saga-demo/booking/pom.xml
index 8deb910a..3c39d9dd 100644
--- a/saga-demo/pack-demo/pom.xml
+++ b/saga-demo/booking/pom.xml
@@ -24,8 +24,8 @@
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
-  <artifactId>pack-demo</artifactId>
-  <name>Saga::Demo::Pack</name>
+  <artifactId>booking</artifactId>
+  <name>Saga::Demo::Booking</name>
   <packaging>pom</packaging>
 
   <modules>
diff --git a/saga-demo/conditional-transaction-demo/README.md b/saga-demo/conditional-transaction-demo/README.md
deleted file mode 100755
index 9ae1deb6..00000000
--- a/saga-demo/conditional-transaction-demo/README.md
+++ /dev/null
@@ -1,174 +0,0 @@
-# Conditional Transaction Demo
-This demo simulates a partial backend of an e-commerce application including four services:
-* payment
-* membership
-* inventory
-* supplier
-
-**Note** Please go through the dependency-free-transaction-demo first, before proceeding with this demo. 
-
-## Background
-Many e-commerce sites have membership concept, which will level up when a customer makes a certain amount of purchase.
-Moreover, as goods are sold and the stock drops to a certain level, the e-commerce company needs to fetch more goods from
-its suppliers. Both scenarios introduce conditional transactions. 
-
-## Workflow
-```
-                  /---> if total purchase >= 1K, level up membership
-start ---> make payment ---> dispatch product from inventory ---> end
-                                              \---> if product stock < 10, replenish product from supplier 
-```
-The conditions are business logic and belong to business service. Therefore, the decision to level up membership is made
-in payment service and the decision to replenish products is made in inventory service. Saga is to be informed of service
-decision by adding an additional element `sagaChildren` in service response JSON to indicate which services are to be invoked
-next as shown below.
-```json
-{
-  "customerId": "mike",
-  "body": "Payment made with id xxx for customer mike",
-  "sagaChildren": ["inventory"] 
-}
-```
-
-If `sagaChildren` is empty or not provided in service response, saga will invoke all of its child services. To invoke none
-of them, explicitly return `"sagaChildren": ["none"]`.
-
-If any of the sub-transaction specified in sagaChildren fails, all completed sub-transactions will be compensated as usual,
-when the recovery policy if backward recovery. 
-
-## 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/conditional-transaction-demo with the following command
-```
-docker-compose up
-```
-
-## User Requests
-The request JSON to ensure the workflow order looks like the following:
-```json
-{
-  "policy": "BackwardRecovery",
-  "requests": [
-    {
-      "id": "payment",
-      "type": "rest",
-      "serviceName": "payment.servicecomb.io:8080",
-      "transaction": {
-        "method": "post",
-        "path": "/payment",
-        "params": {
-          "form": {
-            "customerId": "mike",
-            "purchaseAmount": 400
-          }
-        }
-      },
-      "compensation": {
-        "method": "put",
-        "path": "/payment",
-        "params": {
-          "form": {
-            "customerId": "mike"
-          }
-        }
-      }
-    },
-    {
-      "id": "membership",
-      "type": "rest",
-      "serviceName": "membership.servicecomb.io:8080",
-      "parents": [
-        "payment"
-      ],
-      "transaction": {
-        "method": "post",
-        "path": "/membership",
-        "params": {
-          "form": {
-            "customerId": "mike"
-          }
-        }
-      },
-      "compensation": {
-        "method": "put",
-        "path": "/membership",
-        "params": {
-          "form": {
-            "customerId": "mike"
-          }
-        }
-      }
-    },
-    {
-      "id": "inventory",
-      "type": "rest",
-      "serviceName": "inventory.servicecomb.io:8080",
-      "parents": [
-        "payment"
-      ],
-      "transaction": {
-        "method": "post",
-        "path": "/inventory",
-        "params": {
-          "form": {
-            "customerId": "mike"
-          }
-        }
-      },
-      "compensation": {
-        "method": "put",
-        "path": "/inventory",
-        "params": {
-          "form": {
-            "customerId": "mike"
-          }
-        }
-      }
-    },
-    {
-      "id": "supplier",
-      "type": "rest",
-      "serviceName": "supplier.servicecomb.io:8080",
-      "parents": [
-        "inventory"
-      ],
-      "transaction": {
-        "method": "post",
-        "path": "/supplier",
-        "params": {
-          "form": {
-            "customerId": "servicecomb_mall"
-          }
-        }
-      },
-      "compensation": {
-        "method": "put",
-        "path": "/supplier",
-        "params": {
-          "form": {
-            "customerId": "servicecomb_mall"
-          }
-        }
-      }
-    }
-  ]
-}
-
-```
-
-To send the above JSON request to Saga, use [postman](https://www.getpostman.com/postman) with POST request to url `http://<docker.host.ip>:8083/requests`
-
-Each request to payment service will increase user mike's total purchase by $400. The 3<sup>rd</sup> request will trigger 
-membership level up.
-
-The initial product stock is 11 in inventory and each request to inventory service will deduct product stock by 1. 
-So the 2<sup>nd</sup> request will trigger product replenishment from supplier.
-
-**Note** transactions and compensations implemented by services must be idempotent. In this demo, we did not enforce that
-for simplicity.
-
-To see all events generated by Saga, visit `http://<docker.host.ip>:8083/events` with postman.
diff --git a/saga-demo/conditional-transaction-demo/conditional-transaction-demo-tests/pom.xml b/saga-demo/conditional-transaction-demo/conditional-transaction-demo-tests/pom.xml
deleted file mode 100644
index ffe53b19..00000000
--- a/saga-demo/conditional-transaction-demo/conditional-transaction-demo-tests/pom.xml
+++ /dev/null
@@ -1,301 +0,0 @@
-<?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>conditional-transaction-demo</artifactId>
-    <groupId>org.apache.servicecomb.saga.demo</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>conditional-transaction-demo-tests</artifactId>
-  <name>Saga::Demo::Conditional Transaction::Tests</name>
-
-
-  <dependencies>
-    <dependency>
-      <groupId>commons-logging</groupId>
-      <artifactId>commons-logging</artifactId>
-      <version>1.2</version>
-    </dependency>
-    <dependency>
-      <groupId>io.rest-assured</groupId>
-      <artifactId>rest-assured</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.codehaus.groovy</groupId>
-      <artifactId>groovy-all</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>io.fabric8</groupId>
-        <artifactId>docker-maven-plugin</artifactId>
-        <configuration>
-          <images>
-            <image>
-              <name>postgres</name>
-              <alias>postgres</alias>
-              <run>
-                <env>
-                  <POSTGRES_DB>saga</POSTGRES_DB>
-                  <POSTGRES_USER>saga</POSTGRES_USER>
-                  <POSTGRES_PASSWORD>password</POSTGRES_PASSWORD>
-                </env>
-                <wait>
-                  <log>database system is ready to accept connections</log>
-                  <tcp>
-                    <ports>
-                      <port>5432</port>
-                    </ports>
-                  </tcp>
-                  <time>60000</time>
-                </wait>
-                <ports>
-                  <port>postgres.port:5432</port>
-                </ports>
-              </run>
-            </image>
-            <image>
-              <name>payment:${project.version}</name>
-              <alias>payment</alias>
-              <run>
-                <env>
-                  <JAVA_OPTS />
-                </env>
-                <wait>
-                  <log>Tomcat started on port</log>
-                  <tcp>
-                    <ports>
-                      <port>8080</port>
-                    </ports>
-                  </tcp>
-                  <time>120000</time>
-                </wait>
-                <ports>
-                  <port>payment.port:8080</port>
-                </ports>
-              </run>
-            </image>
-            <image>
-              <name>membership:${project.version}</name>
-              <alias>membership</alias>
-              <run>
-                <env>
-                  <JAVA_OPTS />
-                </env>
-                <wait>
-                  <log>Tomcat started on port</log>
-                  <tcp>
-                    <ports>
-                      <port>8080</port>
-                    </ports>
-                  </tcp>
-                  <time>120000</time>
-                </wait>
-                <ports>
-                  <port>membership.port:8080</port>
-                </ports>
-              </run>
-            </image>
-            <image>
-              <name>inventory:${project.version}</name>
-              <alias>inventory</alias>
-              <run>
-                <env>
-                  <JAVA_OPTS />
-                </env>
-                <wait>
-                  <log>Tomcat started on port</log>
-                  <tcp>
-                    <ports>
-                      <port>8080</port>
-                    </ports>
-                  </tcp>
-                  <time>120000</time>
-                </wait>
-                <ports>
-                  <port>inventory.port:8080</port>
-                </ports>
-              </run>
-            </image>
-            <image>
-              <name>supplier:${project.version}</name>
-              <alias>supplier</alias>
-              <run>
-                <env>
-                  <JAVA_OPTS />
-                </env>
-                <wait>
-                  <log>Tomcat started on port</log>
-                  <tcp>
-                    <ports>
-                      <port>8080</port>
-                    </ports>
-                  </tcp>
-                  <time>120000</time>
-                </wait>
-                <ports>
-                  <port>supplier.port:8080</port>
-                </ports>
-              </run>
-            </image>
-            <image>
-              <name>saga-spring:${project.version}</name>
-              <alias>saga</alias>
-              <run>
-                <env>
-                  <JAVA_OPTS>
-                    -Dspring.profiles.active=prd -Dspring.main.webEnvironment=true
-                  </JAVA_OPTS>
-                </env>
-                <links>
-                  <link>postgres:postgres.servicecomb.io</link>
-                  <link>payment:payment.servicecomb.io</link>
-                  <link>membership:membership.servicecomb.io</link>
-                  <link>inventory:inventory.servicecomb.io</link>
-                  <link>supplier:supplier.servicecomb.io</link>
-                </links>
-                <wait>
-                  <log>Tomcat started on port</log>
-                  <tcp>
-                    <ports>
-                      <port>8080</port>
-                    </ports>
-                  </tcp>
-                  <time>120000</time>
-                </wait>
-                <ports>
-                  <port>saga.port:8080</port>
-                </ports>
-                <dependsOn>
-                  <dependsOn>postgres</dependsOn>
-                </dependsOn>
-              </run>
-            </image>
-          </images>
-        </configuration>
-        <executions>
-          <execution>
-            <id>start</id>
-            <phase>pre-integration-test</phase>
-            <goals>
-              <goal>start</goal>
-            </goals>
-          </execution>
-          <execution>
-            <id>stop</id>
-            <phase>post-integration-test</phase>
-            <goals>
-              <goal>stop</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-  <profiles>
-    <profile>
-      <id>docker</id>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.codehaus.gmaven</groupId>
-            <artifactId>gmaven-plugin</artifactId>
-            <executions>
-              <execution>
-                <id>add-default-properties</id>
-                <phase>initialize</phase>
-                <goals>
-                  <goal>execute</goal>
-                </goals>
-                <configuration>
-                  <source>
-                    project.properties.setProperty('docker.hostname', 'localhost')
-                    log.info("Docker hostname is " + project.properties['docker.hostname'])
-                  </source>
-                </configuration>
-              </execution>
-            </executions>
-          </plugin>
-          <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-failsafe-plugin</artifactId>
-            <version>${maven.failsafe.version}</version>
-            <configuration>
-              <systemPropertyVariables>
-                <saga.address>
-                  http://${docker.hostname}:${saga.port}
-                </saga.address>
-              </systemPropertyVariables>
-              <argLine>${jacoco.failsafe.argLine}</argLine>
-            </configuration>
-            <executions>
-              <execution>
-                <goals>
-                  <goal>integration-test</goal>
-                  <goal>verify</goal>
-                </goals>
-              </execution>
-            </executions>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-    <profile>
-      <id>docker-machine</id>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.codehaus.gmaven</groupId>
-            <artifactId>gmaven-plugin</artifactId>
-            <executions>
-              <execution>
-                <id>add-dynamic-properties</id>
-                <phase>prepare-package</phase>
-                <goals>
-                  <goal>execute</goal>
-                </goals>
-                <configuration>
-                  <source>
-                    def process = "docker-machine ip default".execute()
-                    process.waitFor()
-                    project.properties.setProperty('docker.hostname', process.in.text.trim())
-
-                    log.info("Docker hostname is " + project.properties['docker.hostname'])
-                  </source>
-                </configuration>
-              </execution>
-            </executions>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-  </profiles>
-
-</project>
diff --git a/saga-demo/conditional-transaction-demo/conditional-transaction-demo-tests/src/test/java/org/apache/servicecomb/saga/demo/tests/ConditionalTransactionIT.java b/saga-demo/conditional-transaction-demo/conditional-transaction-demo-tests/src/test/java/org/apache/servicecomb/saga/demo/tests/ConditionalTransactionIT.java
deleted file mode 100644
index d1734d59..00000000
--- a/saga-demo/conditional-transaction-demo/conditional-transaction-demo-tests/src/test/java/org/apache/servicecomb/saga/demo/tests/ConditionalTransactionIT.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * 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.tests;
-
-import static io.restassured.RestAssured.given;
-import static io.restassured.http.ContentType.TEXT;
-import static org.hamcrest.core.Is.is;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-public class ConditionalTransactionIT {
-
-  private static final String requests = "{\n"
-      + "  \"policy\": \"BackwardRecovery\",\n"
-      + "  \"requests\": [\n"
-      + "    {\n"
-      + "      \"id\": \"payment\",\n"
-      + "      \"type\": \"rest\",\n"
-      + "      \"serviceName\": \"payment.servicecomb.io:8080\",\n"
-      + "      \"transaction\": {\n"
-      + "        \"method\": \"post\",\n"
-      + "        \"path\": \"/payment\",\n"
-      + "        \"params\": {\n"
-      + "          \"form\": {\n"
-      + "            \"customerId\": \"mike\",\n"
-      + "            \"purchaseAmount\": 400\n"
-      + "          }\n"
-      + "        }\n"
-      + "      },\n"
-      + "      \"compensation\": {\n"
-      + "        \"method\": \"put\",\n"
-      + "        \"path\": \"/payment\",\n"
-      + "        \"params\": {\n"
-      + "          \"form\": {\n"
-      + "            \"customerId\": \"mike\"\n"
-      + "          }\n"
-      + "        }\n"
-      + "      }\n"
-      + "    },\n"
-      + "    {\n"
-      + "      \"id\": \"membership\",\n"
-      + "      \"type\": \"rest\",\n"
-      + "      \"serviceName\": \"membership.servicecomb.io:8080\",\n"
-      + "      \"parents\": [\n"
-      + "        \"payment\"\n"
-      + "      ],\n"
-      + "      \"transaction\": {\n"
-      + "        \"method\": \"post\",\n"
-      + "        \"path\": \"/membership\",\n"
-      + "        \"params\": {\n"
-      + "          \"form\": {\n"
-      + "            \"customerId\": \"mike\"\n"
-      + "          }\n"
-      + "        }\n"
-      + "      },\n"
-      + "      \"compensation\": {\n"
-      + "        \"method\": \"put\",\n"
-      + "        \"path\": \"/membership\",\n"
-      + "        \"params\": {\n"
-      + "          \"form\": {\n"
-      + "            \"customerId\": \"mike\"\n"
-      + "          }\n"
-      + "        }\n"
-      + "      }\n"
-      + "    },\n"
-      + "    {\n"
-      + "      \"id\": \"inventory\",\n"
-      + "      \"type\": \"rest\",\n"
-      + "      \"serviceName\": \"inventory.servicecomb.io:8080\",\n"
-      + "      \"parents\": [\n"
-      + "        \"payment\"\n"
-      + "      ],\n"
-      + "      \"transaction\": {\n"
-      + "        \"method\": \"post\",\n"
-      + "        \"path\": \"/inventory\",\n"
-      + "        \"params\": {\n"
-      + "          \"form\": {\n"
-      + "            \"customerId\": \"mike\"\n"
-      + "          }\n"
-      + "        }\n"
-      + "      },\n"
-      + "      \"compensation\": {\n"
-      + "        \"method\": \"put\",\n"
-      + "        \"path\": \"/inventory\",\n"
-      + "        \"params\": {\n"
-      + "          \"form\": {\n"
-      + "            \"customerId\": \"mike\"\n"
-      + "          }\n"
-      + "        }\n"
-      + "      }\n"
-      + "    },\n"
-      + "    {\n"
-      + "      \"id\": \"supplier\",\n"
-      + "      \"type\": \"rest\",\n"
-      + "      \"serviceName\": \"supplier.servicecomb.io:8080\",\n"
-      + "      \"parents\": [\n"
-      + "        \"inventory\"\n"
-      + "      ],\n"
-      + "      \"transaction\": {\n"
-      + "        \"method\": \"post\",\n"
-      + "        \"path\": \"/supplier\",\n"
-      + "        \"params\": {\n"
-      + "          \"form\": {\n"
-      + "            \"customerId\": \"servicecomb_mall\"\n"
-      + "          }\n"
-      + "        }\n"
-      + "      },\n"
-      + "      \"compensation\": {\n"
-      + "        \"method\": \"put\",\n"
-      + "        \"path\": \"/supplier\",\n"
-      + "        \"params\": {\n"
-      + "          \"form\": {\n"
-      + "            \"customerId\": \"servicecomb_mall\"\n"
-      + "          }\n"
-      + "        }\n"
-      + "      }\n"
-      + "    }\n"
-      + "  ]\n"
-      + "}\n";
-
-  private static String sagaAddress;
-
-  @BeforeClass
-  public static void setUp() throws Exception {
-    sagaAddress = System.getProperty("saga.address");
-  }
-
-  @Test
-  public void ableToSendRequestsToServicesThroughSaga() {
-    given()
-        .contentType(TEXT)
-        .body(requests)
-        .when()
-        .post(sagaAddress + "/requests")
-        .then()
-        .statusCode(is(200))
-        .body(is("success"));
-  }
-}
diff --git a/saga-demo/conditional-transaction-demo/docker-compose.yaml b/saga-demo/conditional-transaction-demo/docker-compose.yaml
deleted file mode 100755
index 45c72c3e..00000000
--- a/saga-demo/conditional-transaction-demo/docker-compose.yaml
+++ /dev/null
@@ -1,75 +0,0 @@
-## ---------------------------------------------------------------------------
-## 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
-    ports:
-      - "5432:5432"
-    healthcheck:
-        test: ["CMD-SHELL", "nc -z localhost 5432 &> /dev/null; echo $$?"]
-        interval: 30s
-        timeout: 10s
-        retries: 5
-
-  payment:
-    image: "payment:0.0.3-SNAPSHOT"
-    hostname: payment
-    ports:
-      - "8080"
-
-  membership:
-    image: "membership:0.0.3-SNAPSHOT"
-    hostname: membership
-    ports:
-      - "8080"
-
-  inventory:
-    image: "inventory:0.0.3-SNAPSHOT"
-    hostname: inventory
-    ports:
-      - "8080"
-
-  supplier:
-    image: "supplier:0.0.3-SNAPSHOT"
-    hostname: supplier
-    ports:
-      - "8080"
-
-  saga:
-    image: "saga-spring:0.0.3-SNAPSHOT"
-    hostname: saga
-    links:
-      - "postgres:postgres.servicecomb.io"
-      - "payment:payment.servicecomb.io"
-      - "membership:membership.servicecomb.io"
-      - "inventory:inventory.servicecomb.io"
-      - "supplier:supplier.servicecomb.io"
-    environment:
-      - JAVA_OPTS=-Dspring.profiles.active=prd -Dspring.main.webEnvironment=true
-    ports:
-      - "8083:8080"
-    depends_on:
-      postgres:
-        condition: service_healthy
diff --git a/saga-demo/conditional-transaction-demo/inventory/pom.xml b/saga-demo/conditional-transaction-demo/inventory/pom.xml
deleted file mode 100644
index 281ea347..00000000
--- a/saga-demo/conditional-transaction-demo/inventory/pom.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-<?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>conditional-transaction-demo</artifactId>
-    <groupId>org.apache.servicecomb.saga.demo</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>inventory</artifactId>
-  <name>Saga::Demo::Conditional Transaction::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>
-  </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/conditional-transaction-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/inventory/InventoryApplication.java b/saga-demo/conditional-transaction-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/inventory/InventoryApplication.java
deleted file mode 100644
index f0b8e68d..00000000
--- a/saga-demo/conditional-transaction-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/inventory/InventoryApplication.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.conditional.transaction.inventory;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-@SpringBootApplication
-public class InventoryApplication {
-
-  public static void main(String[] args) {
-    SpringApplication.run(InventoryApplication.class, args);
-  }
-}
diff --git a/saga-demo/conditional-transaction-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/inventory/InventoryController.java b/saga-demo/conditional-transaction-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/inventory/InventoryController.java
deleted file mode 100644
index 1f829555..00000000
--- a/saga-demo/conditional-transaction-demo/inventory/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/inventory/InventoryController.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.conditional.transaction.inventory;
-
-import static org.springframework.http.HttpStatus.BAD_REQUEST;
-import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
-import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE;
-import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE;
-import static org.springframework.web.bind.annotation.RequestMethod.POST;
-import static org.springframework.web.bind.annotation.RequestMethod.PUT;
-
-import java.io.IOException;
-import java.util.UUID;
-
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-@Controller
-@RequestMapping("/")
-public class InventoryController {
-  private static final int FETCH_THRESHOLD = 10;
-  private static final String CUSTOMER_ID = "customerId";
-  private final ObjectMapper objectMapper = new ObjectMapper();
-
-  private int stock = 11;
-
-  @RequestMapping(value = "inventory", method = POST, consumes = APPLICATION_FORM_URLENCODED_VALUE, produces = TEXT_PLAIN_VALUE)
-  public ResponseEntity<String> dispatch(@RequestParam String response) {
-    try {
-      ObjectNode jsonNodes = objectMapper.readValue(response, ObjectNode.class);
-      if (jsonNodes.has(CUSTOMER_ID)) {
-        String customerId = jsonNodes.get(CUSTOMER_ID).textValue();
-
-        stock--;
-        if (isStockShort()) {
-          // when no sagaChildren is provided, all child sub-transaction of inventory will be run
-          return response(customerId, "");
-        }
-
-        // select no child sub-transaction to run next, by specifying none in sagaChildren
-        return response(customerId,",  \"sagaChildren\": [\"none\"] \n");
-      }
-      return new ResponseEntity<>("Customer Id is missing", BAD_REQUEST);
-    } catch (IOException e) {
-      return new ResponseEntity<>(e.getMessage(), INTERNAL_SERVER_ERROR);
-    }
-  }
-
-  @RequestMapping(value = "inventory", method = PUT, consumes = APPLICATION_FORM_URLENCODED_VALUE, produces = TEXT_PLAIN_VALUE)
-  public ResponseEntity<String> recall(@RequestParam String customerId) {
-    stock++;
-    return ResponseEntity.ok(String.format("Dispatch recalled with id %s for customer %s",
-        UUID.randomUUID().toString(),
-        customerId));
-  }
-
-  private ResponseEntity<String> response(String customerId, String optionalSagaChildren) {
-    return ResponseEntity.ok(String.format("{\n"
-            + "  \"body\": \"Goods dispatched with id %s for customer %s\"\n"
-            + optionalSagaChildren
-            + "}",
-        UUID.randomUUID().toString(),
-        customerId));
-  }
-
-  private boolean isStockShort() {
-    return stock < FETCH_THRESHOLD;
-  }
-}
diff --git a/saga-demo/conditional-transaction-demo/inventory/src/test/java/org/apache/servicecomb/saga/demo/conditional/transaction/inventory/InventoryControllerTest.java b/saga-demo/conditional-transaction-demo/inventory/src/test/java/org/apache/servicecomb/saga/demo/conditional/transaction/inventory/InventoryControllerTest.java
deleted file mode 100644
index d58a6100..00000000
--- a/saga-demo/conditional-transaction-demo/inventory/src/test/java/org/apache/servicecomb/saga/demo/conditional/transaction/inventory/InventoryControllerTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.conditional.transaction.inventory;
-
-import static org.hamcrest.core.Is.is;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
-import org.springframework.http.MediaType;
-import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.test.web.servlet.MockMvc;
-
-@RunWith(SpringRunner.class)
-@WebMvcTest(InventoryController.class)
-public class InventoryControllerTest {
-  private static final String content = "response=" + encode("{\n"
-      + "  \"customerId\": \"mike\",\n"
-      + "  \"foo\": \"bar\"\n"
-      + "}");
-
-  private static String encode(String param) {
-    try {
-      return URLEncoder.encode(param, "UTF-8");
-    } catch (UnsupportedEncodingException e) {
-      throw new IllegalArgumentException(e);
-    }
-  }
-
-  @Autowired
-  private MockMvc mockMvc;
-
-  @Test
-  public void respondWithChildren_IfStockIsLowerThanThreshold() throws Exception {
-    mockMvc.perform(post("/inventory")
-        .contentType(MediaType.APPLICATION_FORM_URLENCODED)
-        .content(content))
-        .andExpect(status().isOk())
-        .andExpect(jsonPath("$.sagaChildren[0]", is("none")));
-
-    mockMvc.perform(post("/inventory")
-        .contentType(MediaType.APPLICATION_FORM_URLENCODED)
-        .content(content))
-        .andExpect(status().isOk())
-        .andExpect(jsonPath("$.sagaChildren[0]").doesNotExist());
-  }
-
-  @Test
-  public void badRequestIfCustomerIdIsNotInRequestContent() throws Exception {
-    String content = "response=" + encode("{}");
-
-    mockMvc.perform(post("/inventory")
-        .contentType(MediaType.APPLICATION_FORM_URLENCODED)
-        .content(content))
-        .andExpect(status().isBadRequest());
-  }
-}
diff --git a/saga-demo/conditional-transaction-demo/membership/pom.xml b/saga-demo/conditional-transaction-demo/membership/pom.xml
deleted file mode 100644
index b219945a..00000000
--- a/saga-demo/conditional-transaction-demo/membership/pom.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-<?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>conditional-transaction-demo</artifactId>
-    <groupId>org.apache.servicecomb.saga.demo</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>membership</artifactId>
-  <name>Saga::Demo::Conditional Transaction::Membership</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>
-  </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/conditional-transaction-demo/membership/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/membership/MembershipApplication.java b/saga-demo/conditional-transaction-demo/membership/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/membership/MembershipApplication.java
deleted file mode 100644
index 4be73001..00000000
--- a/saga-demo/conditional-transaction-demo/membership/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/membership/MembershipApplication.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.conditional.transaction.membership;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-@SpringBootApplication
-public class MembershipApplication {
-
-  public static void main(String[] args) {
-    SpringApplication.run(MembershipApplication.class, args);
-  }
-}
diff --git a/saga-demo/conditional-transaction-demo/membership/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/membership/MembershipController.java b/saga-demo/conditional-transaction-demo/membership/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/membership/MembershipController.java
deleted file mode 100644
index f7efc393..00000000
--- a/saga-demo/conditional-transaction-demo/membership/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/membership/MembershipController.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.conditional.transaction.membership;
-
-import static java.util.Collections.singleton;
-import static org.springframework.http.HttpStatus.FORBIDDEN;
-import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE;
-import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE;
-import static org.springframework.web.bind.annotation.RequestMethod.POST;
-import static org.springframework.web.bind.annotation.RequestMethod.PUT;
-
-import java.util.Set;
-
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-
-@Controller
-@RequestMapping("/")
-public class MembershipController {
-
-  private final Set<String> customers = singleton("mike");
-
-  @RequestMapping(value = "membership", method = POST, consumes = APPLICATION_FORM_URLENCODED_VALUE, produces = TEXT_PLAIN_VALUE)
-  public ResponseEntity<String> levelUp(@RequestParam String customerId) {
-    if (!customers.contains(customerId)) {
-      return new ResponseEntity<>("No such customer with id " + customerId, FORBIDDEN);
-    }
-
-    return ResponseEntity.ok(String.format("{\n"
-            + "  \"body\": \"Level up customer %s to silver member\"\n"
-            + "}",
-        customerId));
-  }
-
-  @RequestMapping(value = "membership", method = PUT, consumes = APPLICATION_FORM_URLENCODED_VALUE, produces = TEXT_PLAIN_VALUE)
-  public ResponseEntity<String> levelDown(@RequestParam String customerId) {
-    if (!customers.contains(customerId)) {
-      return new ResponseEntity<>("No such customer with id " + customerId, FORBIDDEN);
-    }
-
-    return ResponseEntity.ok(String.format("Level down customer %s to bronze member",
-        customerId));
-  }
-
-}
diff --git a/saga-demo/conditional-transaction-demo/payment/pom.xml b/saga-demo/conditional-transaction-demo/payment/pom.xml
deleted file mode 100644
index 1792916b..00000000
--- a/saga-demo/conditional-transaction-demo/payment/pom.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-<?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>conditional-transaction-demo</artifactId>
-    <groupId>org.apache.servicecomb.saga.demo</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>payment</artifactId>
-  <name>Saga::Demo::Conditional Transaction::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>
-  </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/conditional-transaction-demo/payment/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/payment/PaymentApplication.java b/saga-demo/conditional-transaction-demo/payment/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/payment/PaymentApplication.java
deleted file mode 100644
index 7e0a643b..00000000
--- a/saga-demo/conditional-transaction-demo/payment/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/payment/PaymentApplication.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.conditional.transaction.payment;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-@SpringBootApplication
-public class PaymentApplication {
-
-  public static void main(String[] args) {
-    SpringApplication.run(PaymentApplication.class, args);
-  }
-}
diff --git a/saga-demo/conditional-transaction-demo/payment/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/payment/PaymentController.java b/saga-demo/conditional-transaction-demo/payment/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/payment/PaymentController.java
deleted file mode 100644
index 531414b0..00000000
--- a/saga-demo/conditional-transaction-demo/payment/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/payment/PaymentController.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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.conditional.transaction.payment;
-
-import static java.util.Collections.singletonMap;
-import static org.springframework.http.HttpStatus.FORBIDDEN;
-import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE;
-import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE;
-import static org.springframework.web.bind.annotation.RequestMethod.POST;
-import static org.springframework.web.bind.annotation.RequestMethod.PUT;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-
-@Controller
-@RequestMapping("/")
-public class PaymentController {
-  private static final int UPGRADE_THRESHOLD = 1000;
-
-  private final Map<String, Integer> customerPurchases = new HashMap<>(singletonMap("mike", 0));
-
-  @RequestMapping(value = "payment", method = POST, consumes = APPLICATION_FORM_URLENCODED_VALUE, produces = TEXT_PLAIN_VALUE)
-  public ResponseEntity<String> purchase(@RequestParam String customerId, @RequestParam int purchaseAmount) {
-    if (!customerPurchases.containsKey(customerId)) {
-      return new ResponseEntity<>("No such customer with id " + customerId, FORBIDDEN);
-    }
-
-    customerPurchases.compute(customerId, (id, purchases) -> purchases + purchaseAmount);
-
-    if (isUpgradable(customerId)) {
-      // when no sagaChildren is provided, all child sub-transaction of payment will be run
-      return response(customerId, "");
-    }
-
-    // select only sub-transaction of inventory service to run next, by specifying inventory in sagaChildren
-    return response(customerId, ",  \"sagaChildren\": [\"inventory\"] \n");
-  }
-
-  @RequestMapping(value = "payment", method = PUT, consumes = APPLICATION_FORM_URLENCODED_VALUE, produces = TEXT_PLAIN_VALUE)
-  public ResponseEntity<String> refund(@RequestParam String customerId) {
-    if (!customerPurchases.containsKey(customerId)) {
-      return new ResponseEntity<>("No such customer with id " + customerId, FORBIDDEN);
-    }
-
-    return ResponseEntity.ok(String.format("Payment refunded with id %s for customer %s",
-        UUID.randomUUID().toString(),
-        customerId));
-  }
-
-  private ResponseEntity<String> response(String customerId, String optionalSagaChildren) {
-    return ResponseEntity.ok(String.format("{\n"
-            + "  \"customerId\": \"mike\",\n"
-            + "  \"body\": \"Payment made with id %s for customer %s\"\n"
-            + optionalSagaChildren
-            + "}",
-        UUID.randomUUID().toString(),
-        customerId));
-  }
-
-  private boolean isUpgradable(String customerId) {
-    return customerPurchases.get(customerId) >= UPGRADE_THRESHOLD;
-  }
-}
diff --git a/saga-demo/conditional-transaction-demo/payment/src/test/java/org/apache/servicecomb/saga/demo/conditional/transaction/payment/PaymentControllerTest.java b/saga-demo/conditional-transaction-demo/payment/src/test/java/org/apache/servicecomb/saga/demo/conditional/transaction/payment/PaymentControllerTest.java
deleted file mode 100644
index 99e61871..00000000
--- a/saga-demo/conditional-transaction-demo/payment/src/test/java/org/apache/servicecomb/saga/demo/conditional/transaction/payment/PaymentControllerTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.conditional.transaction.payment;
-
-import static org.hamcrest.core.Is.is;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
-import org.springframework.http.MediaType;
-import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.test.web.servlet.MockMvc;
-
-@RunWith(SpringRunner.class)
-@WebMvcTest(PaymentController.class)
-public class PaymentControllerTest {
-  private static final String requestContent = "customerId=mike&purchaseAmount=400";
-
-  @Autowired
-  private MockMvc mockMvc;
-
-  @Test
-  public void respondWithChildren_IfTotalPurchaseIsLowerThanThreshold() throws Exception {
-    mockMvc.perform(post("/payment")
-        .contentType(MediaType.APPLICATION_FORM_URLENCODED)
-        .content(requestContent))
-        .andExpect(status().isOk())
-        .andExpect(jsonPath("$.sagaChildren[0]", is("inventory")));
-
-    mockMvc.perform(post("/payment")
-        .contentType(MediaType.APPLICATION_FORM_URLENCODED)
-        .content(requestContent))
-        .andExpect(status().isOk())
-        .andExpect(jsonPath("$.sagaChildren[0]", is("inventory")));
-
-    mockMvc.perform(post("/payment")
-        .contentType(MediaType.APPLICATION_FORM_URLENCODED)
-        .content(requestContent))
-        .andExpect(status().isOk())
-        .andExpect(jsonPath("$.sagaChildren[0]").doesNotExist());
-  }
-}
diff --git a/saga-demo/conditional-transaction-demo/pom.xml b/saga-demo/conditional-transaction-demo/pom.xml
deleted file mode 100644
index 97fe0901..00000000
--- a/saga-demo/conditional-transaction-demo/pom.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?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>conditional-transaction-demo</artifactId>
-  <name>Saga::Demo::Conditional Transaction</name>
-  <packaging>pom</packaging>
-
-  <modules>
-    <module>payment</module>
-    <module>membership</module>
-    <module>inventory</module>
-    <module>supplier</module>
-    <module>conditional-transaction-demo-tests</module>
-  </modules>
-
-
-</project>
diff --git a/saga-demo/conditional-transaction-demo/supplier/pom.xml b/saga-demo/conditional-transaction-demo/supplier/pom.xml
deleted file mode 100644
index e5c59647..00000000
--- a/saga-demo/conditional-transaction-demo/supplier/pom.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-<?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>conditional-transaction-demo</artifactId>
-    <groupId>org.apache.servicecomb.saga.demo</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>supplier</artifactId>
-  <name>Saga::Demo::Conditional Transaction::Supplier</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>
-  </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/conditional-transaction-demo/supplier/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/supplier/SupplierApplication.java b/saga-demo/conditional-transaction-demo/supplier/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/supplier/SupplierApplication.java
deleted file mode 100644
index e6729d92..00000000
--- a/saga-demo/conditional-transaction-demo/supplier/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/supplier/SupplierApplication.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.conditional.transaction.supplier;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-@SpringBootApplication
-public class SupplierApplication {
-
-  public static void main(String[] args) {
-    SpringApplication.run(SupplierApplication.class, args);
-  }
-}
diff --git a/saga-demo/conditional-transaction-demo/supplier/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/supplier/SupplierController.java b/saga-demo/conditional-transaction-demo/supplier/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/supplier/SupplierController.java
deleted file mode 100644
index bd71070c..00000000
--- a/saga-demo/conditional-transaction-demo/supplier/src/main/java/org/apache/servicecomb/saga/demo/conditional/transaction/supplier/SupplierController.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.conditional.transaction.supplier;
-
-import static java.util.Collections.singleton;
-import static org.springframework.http.HttpStatus.FORBIDDEN;
-import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE;
-import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE;
-import static org.springframework.web.bind.annotation.RequestMethod.POST;
-
-import java.util.Set;
-import java.util.UUID;
-
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-
-@Controller
-@RequestMapping("/")
-public class SupplierController {
-
-  private final Set<String> customers = singleton("servicecomb_mall");
-
-  @RequestMapping(value = "supplier", method = POST, consumes = APPLICATION_FORM_URLENCODED_VALUE, produces = TEXT_PLAIN_VALUE)
-  public ResponseEntity<String> supply(@RequestParam String customerId) {
-    if (!customers.contains(customerId)) {
-      return new ResponseEntity<>("No such customer with id " + customerId, FORBIDDEN);
-    }
-
-    return ResponseEntity.ok(String.format("{\n"
-            + "  \"body\": \"Goods supply with id %s on the way for customer %s\"\n"
-            + "}",
-        UUID.randomUUID().toString(),
-        customerId));
-  }
-}
diff --git a/saga-demo/conditional-transaction-demo/supplier/src/main/resources/META-INF/LICENSE.txt b/saga-demo/conditional-transaction-demo/supplier/src/main/resources/META-INF/LICENSE.txt
deleted file mode 100644
index d6456956..00000000
--- a/saga-demo/conditional-transaction-demo/supplier/src/main/resources/META-INF/LICENSE.txt
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed 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.
diff --git a/saga-demo/conditional-transaction-demo/supplier/src/main/resources/META-INF/NOTICE.txt b/saga-demo/conditional-transaction-demo/supplier/src/main/resources/META-INF/NOTICE.txt
deleted file mode 100644
index 2e215bf2..00000000
--- a/saga-demo/conditional-transaction-demo/supplier/src/main/resources/META-INF/NOTICE.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-   =========================================================================
-   ==  NOTICE file corresponding to the section 4 d of                    ==
-   ==  the Apache License, Version 2.0,                                   ==
-   ==  in this case for the Apache Camel distribution.                    ==
-   =========================================================================
-
-   This product includes software developed by
-   The Apache Software Foundation (http://www.apache.org/).
-
-   Please read the different LICENSE files present in the licenses directory of
-   this distribution.
diff --git a/saga-demo/dependency-free-transaction-demo/README.md b/saga-demo/dependency-free-transaction-demo/README.md
deleted file mode 100755
index 611dfa5e..00000000
--- a/saga-demo/dependency-free-transaction-demo/README.md
+++ /dev/null
@@ -1,168 +0,0 @@
-# Dependency Free Transaction Demo
-This demo simulates a bare minimal travel application including four services:
-* car rental
-* flight booking
-* hotel reservation
-* payment
-
-## Background
-A user with travel plans may like making car rental, flight booking, and hotel reservation with just a single service 
-instead of three separate services. That's why this application can help.
-
-With microservice architecture, each of the services may have its own database technology and it's not feasible to ensure
-all transactions on these services are either committed or rolled back with database. In this demo, we make use of Saga to
-ensure eventual data consistency among services.
-
-## Architecture
-
-```
-               
-               /----> car rental service
-User ---> Saga -----> flight booking service
-               \----> hotel reservation service
-                \---> payment service
-```
-
-## 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/dependency-free-transaction-demo with the following command
-```
-docker-compose up
-```
-
-## User Requests
-A user normally expects to make payment only when transactions with all three services are completed successfully. So Saga
-will talk to car rental, flight booking, and hotel reservation services in parallel and then payment service only when the
-former three services return success.
-
-The request JSON to ensure this process order looks like the following:
-```json
-{
-  "policy": "BackwardRecovery",
-  "requests": [
-    {
-      "id": "request-car",
-      "type": "rest",
-      "serviceName": "car-rental-service",
-      "transaction": {
-        "method": "post",
-        "path": "/rentals",
-        "params": {
-          "form": {
-            "customerId": "mike"
-          }
-        }
-      },
-      "compensation": {
-        "method": "put",
-        "path": "/rentals",
-        "params": {
-          "form": {
-            "customerId": "mike"
-          }
-        }
-      }
-    },
-    {
-      "id": "request-hotel",
-      "type": "rest",
-      "serviceName": "hotel-reservation-service",
-      "transaction": {
-        "method": "post",
-        "path": "/reservations",
-        "params": {
-          "form": {
-            "customerId": "mike"
-          }
-        }
-      },
-      "compensation": {
-        "method": "put",
-        "path": "/reservations",
-        "params": {
-          "form": {
-            "customerId": "mike"
-          }
-        }
-      }
-    },
-    {
-      "id": "request-flight",
-      "type": "rest",
-      "serviceName": "flight-booking-service",
-      "transaction": {
-        "method": "post",
-        "path": "/bookings",
-        "params": {
-          "form": {
-            "customerId": "mike"
-          }
-        }
-      },
-      "compensation": {
-        "method": "put",
-        "path": "/bookings",
-        "params": {
-          "form": {
-            "customerId": "mike"
-          }
-        }
-      }
-    },
-    {
-      "id": "request-payment",
-      "type": "rest",
-      "serviceName": "saga-crossapp:payment-service",
-      "parents": [
-        "request-car",
-        "request-flight",
-        "request-hotel"
-      ],
-      "transaction": {
-        "method": "post",
-        "path": "/payments",
-        "params": {
-          "form": {
-            "customerId": "mike"
-          }
-        }
-      },
-      "compensation": {
-        "method": "put",
-        "path": "/payments",
-        "params": {
-          "form": {
-            "customerId": "mike"
-          }
-        }
-      }
-    }
-  ]
-}
-```
-
-The key to the request dependency lies in definition of parents field in the payment request. It means the payment request 
-is only executed after `request-car` , `request-flight` , and `request-hotel` are completed. 
-```
-    "id": "request-payment",
-    "type": "rest",
-    "serviceName": "payment.servicecomb.io:8080",
-    "parents": [
-      "request-car",    // request id to car service in the full request json
-      "request-flight", // request id to flight service in the full request json
-      "request-hotel"   // request id to hotel service in the full request json
-    ]
-```
-
-To send the above JSON request to Saga, use [postman](https://www.getpostman.com/postman) with POST request to url `http://<docker.host.ip>:8083/requests`
-
-Sending the request more than once will trigger compensation due to insufficient account balance in payment-service.
-
-**Note** transactions and compensations implemented by services must be idempotent. In this demo, we did not enforce that
-for simplicity.
-
-To see all events generated by Saga, visit `http://<docker.host.ip>:8083/events` with browser.
diff --git a/saga-demo/dependency-free-transaction-demo/car-rental-service/pom.xml b/saga-demo/dependency-free-transaction-demo/car-rental-service/pom.xml
deleted file mode 100644
index d4a3b428..00000000
--- a/saga-demo/dependency-free-transaction-demo/car-rental-service/pom.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-<?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>dependency-free-transaction-demo</artifactId>
-    <groupId>org.apache.servicecomb.saga.demo</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>car-rental-service</artifactId>
-  <name>Saga::Demo::Dependency Free Transaction::Car Rental Service</name>
-
-
-  <dependencies>
-    <dependency>
-      <groupId>io.servicecomb</groupId>
-      <artifactId>spring-boot-starter-provider</artifactId>
-      <exclusions>
-        <exclusion>
-          <groupId>log4j</groupId>
-          <artifactId>log4j</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <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>
-  </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/dependency-free-transaction-demo/car-rental-service/src/main/java/org/apache/servicecomb/saga/demo/car/rental/CarRentalApplication.java b/saga-demo/dependency-free-transaction-demo/car-rental-service/src/main/java/org/apache/servicecomb/saga/demo/car/rental/CarRentalApplication.java
deleted file mode 100644
index d3e0e956..00000000
--- a/saga-demo/dependency-free-transaction-demo/car-rental-service/src/main/java/org/apache/servicecomb/saga/demo/car/rental/CarRentalApplication.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.car.rental;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-import io.servicecomb.springboot.starter.provider.EnableServiceComb;
-
-@SpringBootApplication
-@EnableServiceComb
-public class CarRentalApplication {
-
-  public static void main(String[] args) {
-    SpringApplication.run(CarRentalApplication.class, args);
-  }
-}
diff --git a/saga-demo/dependency-free-transaction-demo/car-rental-service/src/main/java/org/apache/servicecomb/saga/demo/car/rental/CarRentalController.java b/saga-demo/dependency-free-transaction-demo/car-rental-service/src/main/java/org/apache/servicecomb/saga/demo/car/rental/CarRentalController.java
deleted file mode 100644
index 4a98141b..00000000
--- a/saga-demo/dependency-free-transaction-demo/car-rental-service/src/main/java/org/apache/servicecomb/saga/demo/car/rental/CarRentalController.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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.car.rental;
-
-import static java.util.Arrays.asList;
-import static javax.ws.rs.core.Response.Status.FORBIDDEN;
-import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
-import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE;
-import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE;
-import static org.springframework.web.bind.annotation.RequestMethod.POST;
-import static org.springframework.web.bind.annotation.RequestMethod.PUT;
-
-import java.lang.invoke.MethodHandles;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestAttribute;
-import org.springframework.web.bind.annotation.RequestMapping;
-
-import io.servicecomb.provider.rest.common.RestSchema;
-import io.servicecomb.swagger.invocation.exception.InvocationException;
-import io.swagger.annotations.ApiResponse;
-import io.swagger.annotations.ApiResponses;
-
-@Controller
-@RequestMapping("/")
-@RestSchema(schemaId = "car-endpoint")
-public class CarRentalController {
-  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-  private final Set<String> customers = new HashSet<>(asList("mike", "snail"));
-  private int delay = 60;
-
-  @ApiResponses({
-      @ApiResponse(code = 200, response = String.class, message = "authenticated user"),
-      @ApiResponse(code = 403, response = String.class, message = "unauthenticated user")
-  })
-  @RequestMapping(value = "rentals", method = POST, consumes = APPLICATION_FORM_URLENCODED_VALUE, produces = TEXT_PLAIN_VALUE)
-  public ResponseEntity<String> rent(@RequestAttribute String customerId) {
-    log.info("Received car rental request from customer {}", customerId);
-    if (!customers.contains(customerId)) {
-      log.info("No such customer {}", customerId);
-      throw new InvocationException(FORBIDDEN, "No such customer with id " + customerId);
-    }
-
-    if ("snail".equals(customerId)) {
-      try {
-        log.info("Encountered extremely slow customer {}", customerId);
-        int timeout = delay;
-        delay = 0;
-        TimeUnit.SECONDS.sleep(timeout);
-        log.info("Finally served the extremely slow customer {}", customerId);
-      } catch (InterruptedException e) {
-        return new ResponseEntity<>("Interrupted", INTERNAL_SERVER_ERROR);
-      }
-    }
-
-    return ResponseEntity.ok(String.format("{\n"
-            + "  \"body\": \"Car rented with id %s for customer %s\"\n"
-            + "}",
-        UUID.randomUUID().toString(),
-        customerId));
-  }
-
-  @ApiResponses({
-      @ApiResponse(code = 200, response = String.class, message = "authenticated user"),
-      @ApiResponse(code = 403, response = String.class, message = "unauthenticated user")
-  })
-  @RequestMapping(value = "rentals", method = PUT, consumes = APPLICATION_FORM_URLENCODED_VALUE, produces = TEXT_PLAIN_VALUE)
-  public ResponseEntity<String> cancel(@RequestAttribute String customerId) {
-    if (!customers.contains(customerId)) {
-      throw new InvocationException(FORBIDDEN, "No such customer with id " + customerId);
-    }
-
-    return ResponseEntity.ok(String.format("Car rental cancelled with id %s for customer %s",
-        UUID.randomUUID().toString(),
-        customerId));
-  }
-}
diff --git a/saga-demo/dependency-free-transaction-demo/car-rental-service/src/main/resources/microservice.yaml b/saga-demo/dependency-free-transaction-demo/car-rental-service/src/main/resources/microservice.yaml
deleted file mode 100644
index c60e75aa..00000000
--- a/saga-demo/dependency-free-transaction-demo/car-rental-service/src/main/resources/microservice.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-## ---------------------------------------------------------------------------
-## 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.
-## ---------------------------------------------------------------------------
-APPLICATION_ID: saga
-service_description:
-  name: car-rental-service
-  version: 0.0.1
-cse:
-  service:
-    registry:
-      address: http://sc.servicecomb.io:30100
-  rest:
-    address: 0.0.0.0:8080
-  handler:
-    chain:
-      Consumer:
-        default: loadbalance
diff --git a/saga-demo/dependency-free-transaction-demo/demo-tests/pom.xml b/saga-demo/dependency-free-transaction-demo/demo-tests/pom.xml
deleted file mode 100644
index 038a47a6..00000000
--- a/saga-demo/dependency-free-transaction-demo/demo-tests/pom.xml
+++ /dev/null
@@ -1,333 +0,0 @@
-<?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>dependency-free-transaction-demo</artifactId>
-    <groupId>org.apache.servicecomb.saga.demo</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>demo-tests</artifactId>
-  <name>Saga::Demo::Dependency Free Transaction:: Tests</name>
-
-
-  <dependencies>
-    <dependency>
-      <groupId>commons-logging</groupId>
-      <artifactId>commons-logging</artifactId>
-      <version>1.2</version>
-    </dependency>
-    <dependency>
-      <groupId>io.rest-assured</groupId>
-      <artifactId>rest-assured</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.codehaus.groovy</groupId>
-      <artifactId>groovy-all</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>io.fabric8</groupId>
-        <artifactId>docker-maven-plugin</artifactId>
-        <configuration>
-          <images>
-            <image>
-              <name>servicecomb/service-center:latest</name>
-              <alias>service-center</alias>
-              <run>
-                <wait>
-                  <log>Local listen address</log>
-                  <tcp>
-                    <ports>
-                      <port>30100</port>
-                    </ports>
-                  </tcp>
-                  <time>60000</time>
-                </wait>
-                <ports>
-                  <port>service.center.port:30100</port>
-                </ports>
-              </run>
-            </image>
-            <image>
-              <name>postgres</name>
-              <alias>postgres</alias>
-              <run>
-                <env>
-                  <POSTGRES_DB>saga</POSTGRES_DB>
-                  <POSTGRES_USER>saga</POSTGRES_USER>
-                  <POSTGRES_PASSWORD>password</POSTGRES_PASSWORD>
-                </env>
-                <wait>
-                  <log>database system is ready to accept connections</log>
-                  <tcp>
-                    <ports>
-                      <port>5432</port>
-                    </ports>
-                  </tcp>
-                  <time>60000</time>
-                </wait>
-                <ports>
-                  <port>postgres.port:5432</port>
-                </ports>
-              </run>
-            </image>
-            <image>
-              <name>car-rental-service:${project.version}</name>
-              <alias>car</alias>
-              <run>
-                <env>
-                  <JAVA_OPTS />
-                </env>
-                <wait>
-                  <log>Started [a-zA-Z]+ in [0-9.]+ seconds</log>
-                  <tcp>
-                    <ports>
-                      <port>8080</port>
-                    </ports>
-                  </tcp>
-                  <time>120000</time>
-                </wait>
-                <links>
-                  <link>service-center:sc.servicecomb.io</link>
-                </links>
-                <ports>
-                  <port>car.port:8080</port>
-                </ports>
-              </run>
-            </image>
-            <image>
-              <name>flight-booking-service:${project.version}</name>
-              <alias>flight</alias>
-              <run>
-                <env>
-                  <JAVA_OPTS />
-                </env>
-                <wait>
-                  <log>Started [a-zA-Z]+ in [0-9.]+ seconds</log>
-                  <tcp>
-                    <ports>
-                      <port>8080</port>
-                    </ports>
-                  </tcp>
-                  <time>120000</time>
-                </wait>
-                <links>
-                  <link>service-center:sc.servicecomb.io</link>
-                </links>
-                <ports>
-                  <port>flight.port:8080</port>
-                </ports>
-              </run>
-            </image>
-            <image>
-              <name>hotel-reservation-service:${project.version}</name>
-              <alias>hotel</alias>
-              <run>
-                <env>
-                  <JAVA_OPTS />
-                </env>
-                <wait>
-                  <log>Started [a-zA-Z]+ in [0-9.]+ seconds</log>
-                  <tcp>
-                    <ports>
-                      <port>8080</port>
-                    </ports>
-                  </tcp>
-                  <time>120000</time>
-                </wait>
-                <links>
-                  <link>service-center:sc.servicecomb.io</link>
-                </links>
-                <ports>
-                  <port>hotel.port:8080</port>
-                </ports>
-              </run>
-            </image>
-            <image>
-              <name>payment-service:${project.version}</name>
-              <alias>payment</alias>
-              <run>
-                <env>
-                  <JAVA_OPTS />
-                </env>
-                <wait>
-                  <log>Started [a-zA-Z]+ in [0-9.]+ seconds</log>
-                  <tcp>
-                    <ports>
-                      <port>8080</port>
-                    </ports>
-                  </tcp>
-                  <time>120000</time>
-                </wait>
-                <links>
-                  <link>service-center:sc.servicecomb.io</link>
-                </links>
-                <ports>
-                  <port>payment.port:8080</port>
-                </ports>
-              </run>
-            </image>
-            <image>
-              <name>saga-spring:${project.version}</name>
-              <alias>saga</alias>
-              <run>
-                <env>
-                  <JAVA_OPTS>
-                    -Dspring.profiles.active=prd,servicecomb
-                    -Dcse.service.registry.address=http://sc.servicecomb.io:30100
-                  </JAVA_OPTS>
-                </env>
-                <links>
-                  <link>service-center:sc.servicecomb.io</link>
-                  <link>postgres:postgres.servicecomb.io</link>
-                  <link>car:car.servicecomb.io</link>
-                  <link>flight:flight.servicecomb.io</link>
-                  <link>hotel:hotel.servicecomb.io</link>
-                  <link>payment:payment.servicecomb.io</link>
-                </links>
-                <wait>
-                  <log>Started [a-zA-Z]+ in [0-9.]+ seconds</log>
-                  <tcp>
-                    <ports>
-                      <port>8080</port>
-                    </ports>
-                  </tcp>
-                  <time>120000</time>
-                </wait>
-                <ports>
-                  <port>saga.port:8080</port>
-                </ports>
-                <dependsOn>
-                  <dependsOn>postgres</dependsOn>
-                </dependsOn>
-              </run>
-            </image>
-          </images>
-        </configuration>
-        <executions>
-          <execution>
-            <id>start</id>
-            <phase>pre-integration-test</phase>
-            <goals>
-              <goal>start</goal>
-            </goals>
-          </execution>
-          <execution>
-            <id>stop</id>
-            <phase>post-integration-test</phase>
-            <goals>
-              <goal>stop</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-  <profiles>
-    <profile>
-      <id>docker</id>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.codehaus.gmaven</groupId>
-            <artifactId>gmaven-plugin</artifactId>
-            <executions>
-              <execution>
-                <id>add-default-properties</id>
-                <phase>initialize</phase>
-                <goals>
-                  <goal>execute</goal>
-                </goals>
-                <configuration>
-                  <source>
-                    project.properties.setProperty('docker.hostname', 'localhost')
-                    log.info("Docker hostname is " + project.properties['docker.hostname'])
-                  </source>
-                </configuration>
-              </execution>
-            </executions>
-          </plugin>
-          <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-failsafe-plugin</artifactId>
-            <version>${maven.failsafe.version}</version>
-            <configuration>
-              <systemPropertyVariables>
-                <saga.address>
-                  http://${docker.hostname}:${saga.port}
-                </saga.address>
-              </systemPropertyVariables>
-              <argLine>${jacoco.failsafe.argLine}</argLine>
-            </configuration>
-            <executions>
-              <execution>
-                <goals>
-                  <goal>integration-test</goal>
-                  <goal>verify</goal>
-                </goals>
-              </execution>
-            </executions>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-    <profile>
-      <id>docker-machine</id>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.codehaus.gmaven</groupId>
-            <artifactId>gmaven-plugin</artifactId>
-            <executions>
-              <execution>
-                <id>add-dynamic-properties</id>
-                <phase>prepare-package</phase>
-                <goals>
-                  <goal>execute</goal>
-                </goals>
-                <configuration>
-                  <source>
-                    def process = "docker-machine ip default".execute()
-                    process.waitFor()
-                    project.properties.setProperty('docker.hostname', process.in.text.trim())
-
-                    log.info("Docker hostname is " + project.properties['docker.hostname'])
-                  </source>
-                </configuration>
-              </execution>
-            </executions>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-  </profiles>
-
-</project>
diff --git a/saga-demo/dependency-free-transaction-demo/demo-tests/src/test/java/org/apache/servicecomb/saga/demo/tests/DemoIT.java b/saga-demo/dependency-free-transaction-demo/demo-tests/src/test/java/org/apache/servicecomb/saga/demo/tests/DemoIT.java
deleted file mode 100644
index 750b1e4c..00000000
--- a/saga-demo/dependency-free-transaction-demo/demo-tests/src/test/java/org/apache/servicecomb/saga/demo/tests/DemoIT.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * 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.tests;
-
-import static io.restassured.RestAssured.given;
-import static io.restassured.http.ContentType.TEXT;
-import static org.hamcrest.core.Is.is;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-public class DemoIT {
-
-  private static final String requests = "{\n"
-      + "  \"policy\": \"BackwardRecovery\",\n"
-      + "  \"requests\": [\n"
-      + "    {\n"
-      + "      \"id\": \"request-car\",\n"
-      + "      \"type\": \"rest\",\n"
-      + "      \"serviceName\": \"car-rental-service\",\n"
-      + "      \"transaction\": {\n"
-      + "        \"method\": \"post\",\n"
-      + "        \"path\": \"/rentals\",\n"
-      + "        \"params\": {\n"
-      + "          \"form\": {\n"
-      + "            \"customerId\": \"mike\"\n"
-      + "          }\n"
-      + "        }\n"
-      + "      },\n"
-      + "      \"compensation\": {\n"
-      + "        \"method\": \"put\",\n"
-      + "        \"path\": \"/rentals\",\n"
-      + "        \"params\": {\n"
-      + "          \"form\": {\n"
-      + "            \"customerId\": \"mike\"\n"
-      + "          }\n"
-      + "        }\n"
-      + "      }\n"
-      + "    },\n"
-      + "    {\n"
-      + "      \"id\": \"request-hotel\",\n"
-      + "      \"type\": \"rest\",\n"
-      + "      \"serviceName\": \"hotel-reservation-service\",\n"
-      + "      \"transaction\": {\n"
-      + "        \"method\": \"post\",\n"
-      + "        \"path\": \"/reservations\",\n"
-      + "        \"params\": {\n"
-      + "          \"form\": {\n"
-      + "            \"customerId\": \"mike\"\n"
-      + "          }\n"
-      + "        }\n"
-      + "      },\n"
-      + "      \"compensation\": {\n"
-      + "        \"method\": \"put\",\n"
-      + "        \"path\": \"/reservations\",\n"
-      + "        \"params\": {\n"
-      + "          \"form\": {\n"
-      + "            \"customerId\": \"mike\"\n"
-      + "          }\n"
-      + "        }\n"
-      + "      }\n"
-      + "    },\n"
-      + "    {\n"
-      + "      \"id\": \"request-flight\",\n"
-      + "      \"type\": \"rest\",\n"
-      + "      \"serviceName\": \"flight-booking-service\",\n"
-      + "      \"transaction\": {\n"
-      + "        \"method\": \"post\",\n"
-      + "        \"path\": \"/bookings\",\n"
-      + "        \"params\": {\n"
-      + "          \"form\": {\n"
-      + "            \"customerId\": \"mike\"\n"
-      + "          }\n"
-      + "        }\n"
-      + "      },\n"
-      + "      \"compensation\": {\n"
-      + "        \"method\": \"put\",\n"
-      + "        \"path\": \"/bookings\",\n"
-      + "        \"params\": {\n"
-      + "          \"form\": {\n"
-      + "            \"customerId\": \"mike\"\n"
-      + "          }\n"
-      + "        }\n"
-      + "      }\n"
-      + "    },\n"
-      + "    {\n"
-      + "      \"id\": \"request-payment\",\n"
-      + "      \"type\": \"rest\",\n"
-      + "      \"serviceName\": \"saga-crossapp:payment-service\",\n"
-      + "      \"parents\": [\n"
-      + "        \"request-car\",\n"
-      + "        \"request-flight\",\n"
-      + "        \"request-hotel\"\n"
-      + "      ],\n"
-      + "      \"transaction\": {\n"
-      + "        \"method\": \"post\",\n"
-      + "        \"path\": \"/payments\",\n"
-      + "        \"params\": {\n"
-      + "          \"form\": {\n"
-      + "            \"customerId\": \"mike\"\n"
-      + "          }\n"
-      + "        }\n"
-      + "      },\n"
-      + "      \"compensation\": {\n"
-      + "        \"method\": \"put\",\n"
-      + "        \"path\": \"/payments\",\n"
-      + "        \"params\": {\n"
-      + "          \"form\": {\n"
-      + "            \"customerId\": \"mike\"\n"
-      + "          }\n"
-      + "        }\n"
-      + "      }\n"
-      + "    }\n"
-      + "  ]\n"
-      + "}\n";
-
-  private static String sagaAddress;
-
-  @BeforeClass
-  public static void setUp() throws Exception {
-    sagaAddress = System.getProperty("saga.address");
-  }
-
-  @Test
-  public void ableToSendRequestsToServicesThroughSaga() {
-    given()
-        .contentType(TEXT)
-        .body(requests)
-        .when()
-        .post(sagaAddress + "/requests")
-        .then()
-        .statusCode(is(200))
-        .body(is("success"));
-  }
-}
diff --git a/saga-demo/dependency-free-transaction-demo/docker-compose.yaml b/saga-demo/dependency-free-transaction-demo/docker-compose.yaml
deleted file mode 100755
index c6282bf5..00000000
--- a/saga-demo/dependency-free-transaction-demo/docker-compose.yaml
+++ /dev/null
@@ -1,101 +0,0 @@
-## ---------------------------------------------------------------------------
-## 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:
-  service-center:
-    image: "servicecomb/service-center"
-    hostname: service-center
-    ports:
-      - "30100:30100"
-
-  postgres:
-    image: "postgres"
-    hostname: postgres
-    environment:
-      - POSTGRES_DB=saga
-      - POSTGRES_USER=saga
-      - POSTGRES_PASSWORD=password
-    ports:
-      - "5432:5432"
-    healthcheck:
-        test: ["CMD-SHELL", "nc -z localhost 5432 &> /dev/null; echo $$?"]
-        interval: 30s
-        timeout: 10s
-        retries: 5
-
-  car-rental-service:
-    image: "car-rental-service:0.0.3-SNAPSHOT"
-    hostname: car
-    links:
-      - "service-center:sc.servicecomb.io"
-    ports:
-      - "8080"
-
-  flight-booking-service:
-    image: "flight-booking-service:0.0.3-SNAPSHOT"
-    hostname: flight
-    links:
-      - "service-center:sc.servicecomb.io"
-    ports:
-      - "8080"
-
-  hotel-reservation-service:
-    image: "hotel-reservation-service:0.0.3-SNAPSHOT"
-    hostname: hotel
-    links:
-      - "service-center:sc.servicecomb.io"
-    ports:
-      - "8080"
-
-  payment-service:
-    image: "payment-service:0.0.3-SNAPSHOT"
-    hostname: payment
-    links:
-      - "service-center:sc.servicecomb.io"
-    ports:
-      - "8080"
-
-  saga:
-    image: "saga-spring:0.0.3-SNAPSHOT"
-    hostname: saga
-    links:
-      - "postgres:postgres.servicecomb.io"
-      - "service-center:sc.servicecomb.io"
-      - "car-rental-service:car.servicecomb.io"
-      - "flight-booking-service:flight.servicecomb.io"
-      - "hotel-reservation-service:hotel.servicecomb.io"
-      - "payment-service:payment.servicecomb.io"
-    environment:
-      - JAVA_OPTS=-Dspring.profiles.active=prd,servicecomb -Dcse.service.registry.address=http://sc.servicecomb.io:30100
-    ports:
-      - "8083:8080"
-    depends_on:
-      postgres:
-        condition: service_healthy
-
-  web:
-    image: "saga-web:0.0.3-SNAPSHOT"
-    hostname: web
-    links:
-      - "service-center:sc.servicecomb.io"
-      - "saga:saga.servicecomb.io"
-    environment:
-      - JAVA_OPTS=-Dspring.profiles.active=prd,servicecomb -Dcse.service.registry.address=http://sc.servicecomb.io:30100
-    ports:
-      - "8888:8888"
diff --git a/saga-demo/dependency-free-transaction-demo/flight-booking-service/pom.xml b/saga-demo/dependency-free-transaction-demo/flight-booking-service/pom.xml
deleted file mode 100644
index 3620d350..00000000
--- a/saga-demo/dependency-free-transaction-demo/flight-booking-service/pom.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-<?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>dependency-free-transaction-demo</artifactId>
-    <groupId>org.apache.servicecomb.saga.demo</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>flight-booking-service</artifactId>
-  <name>Saga::Demo::Dependency Free Transaction::Flight Booking Service</name>
-
-
-  <dependencies>
-    <dependency>
-      <groupId>io.servicecomb</groupId>
-      <artifactId>spring-boot-starter-provider</artifactId>
-      <exclusions>
-        <exclusion>
-          <groupId>log4j</groupId>
-          <artifactId>log4j</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <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>
-  </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/dependency-free-transaction-demo/flight-booking-service/src/main/java/org/apache/servicecomb/saga/demo/flight/booking/FlightBookingApplication.java b/saga-demo/dependency-free-transaction-demo/flight-booking-service/src/main/java/org/apache/servicecomb/saga/demo/flight/booking/FlightBookingApplication.java
deleted file mode 100644
index 5bee98d7..00000000
--- a/saga-demo/dependency-free-transaction-demo/flight-booking-service/src/main/java/org/apache/servicecomb/saga/demo/flight/booking/FlightBookingApplication.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.flight.booking;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-import io.servicecomb.springboot.starter.provider.EnableServiceComb;
-
-@SpringBootApplication
-@EnableServiceComb
-public class FlightBookingApplication {
-
-  public static void main(String[] args) {
-    SpringApplication.run(FlightBookingApplication.class, args);
-  }
-}
diff --git a/saga-demo/dependency-free-transaction-demo/flight-booking-service/src/main/java/org/apache/servicecomb/saga/demo/flight/booking/FlightBookingController.java b/saga-demo/dependency-free-transaction-demo/flight-booking-service/src/main/java/org/apache/servicecomb/saga/demo/flight/booking/FlightBookingController.java
deleted file mode 100644
index 37184ace..00000000
--- a/saga-demo/dependency-free-transaction-demo/flight-booking-service/src/main/java/org/apache/servicecomb/saga/demo/flight/booking/FlightBookingController.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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.flight.booking;
-
-import static java.util.Collections.singleton;
-import static javax.ws.rs.core.Response.Status.FORBIDDEN;
-import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE;
-import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE;
-import static org.springframework.web.bind.annotation.RequestMethod.POST;
-import static org.springframework.web.bind.annotation.RequestMethod.PUT;
-
-import java.util.Set;
-import java.util.UUID;
-
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestAttribute;
-import org.springframework.web.bind.annotation.RequestMapping;
-
-import io.servicecomb.provider.rest.common.RestSchema;
-import io.servicecomb.swagger.invocation.exception.InvocationException;
-import io.swagger.annotations.ApiResponse;
-import io.swagger.annotations.ApiResponses;
-
-@Controller
-@RequestMapping("/")
-@RestSchema(schemaId = "flight-endpoint")
-public class FlightBookingController {
-  private final Set<String> customers = singleton("mike");
-
-  @ApiResponses({
-      @ApiResponse(code = 200, response = String.class, message = "authenticated user"),
-      @ApiResponse(code = 403, response = String.class, message = "unauthenticated user")
-  })
-  @RequestMapping(value = "bookings", method = POST, consumes = APPLICATION_FORM_URLENCODED_VALUE, produces = TEXT_PLAIN_VALUE)
-  public ResponseEntity<String> book(@RequestAttribute String customerId) {
-    if (!customers.contains(customerId)) {
-      throw new InvocationException(FORBIDDEN, "No such customer with id " + customerId);
-    }
-
-    return ResponseEntity.ok(String.format("{\n"
-            + "  \"body\": \"Flight booked with id %s for customer %s\"\n"
-            + "}",
-        UUID.randomUUID().toString(),
-        customerId));
-  }
-
-  @ApiResponses({
-      @ApiResponse(code = 200, response = String.class, message = "authenticated user"),
-      @ApiResponse(code = 403, response = String.class, message = "unauthenticated user")
-  })
-  @RequestMapping(value = "bookings", method = PUT, consumes = APPLICATION_FORM_URLENCODED_VALUE, produces = TEXT_PLAIN_VALUE)
-  public ResponseEntity<String> cancel(@RequestAttribute String customerId) {
-    if (!customers.contains(customerId)) {
-      throw new InvocationException(FORBIDDEN, "No such customer with id " + customerId);
-    }
-
-    return ResponseEntity.ok(String.format("Flight booking cancelled with id %s for customer %s",
-        UUID.randomUUID().toString(),
-        customerId));
-  }
-}
diff --git a/saga-demo/dependency-free-transaction-demo/flight-booking-service/src/main/resources/microservice.yaml b/saga-demo/dependency-free-transaction-demo/flight-booking-service/src/main/resources/microservice.yaml
deleted file mode 100644
index fe96db73..00000000
--- a/saga-demo/dependency-free-transaction-demo/flight-booking-service/src/main/resources/microservice.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-## ---------------------------------------------------------------------------
-## 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.
-## ---------------------------------------------------------------------------
-APPLICATION_ID: saga
-service_description:
-  name: flight-booking-service
-  version: 0.0.1
-cse:
-  service:
-    registry:
-      address: http://sc.servicecomb.io:30100
-  rest:
-    address: 0.0.0.0:8080
-  handler:
-    chain:
-      Consumer:
-        default: loadbalance
diff --git a/saga-demo/dependency-free-transaction-demo/hotel-reservation-service/pom.xml b/saga-demo/dependency-free-transaction-demo/hotel-reservation-service/pom.xml
deleted file mode 100644
index dd8ad4b3..00000000
--- a/saga-demo/dependency-free-transaction-demo/hotel-reservation-service/pom.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-<?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>dependency-free-transaction-demo</artifactId>
-    <groupId>org.apache.servicecomb.saga.demo</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>hotel-reservation-service</artifactId>
-  <name>Saga::Demo::Dependency Free Transaction::Hotel Reservation Service</name>
-
-
-  <dependencies>
-    <dependency>
-      <groupId>io.servicecomb</groupId>
-      <artifactId>spring-boot-starter-provider</artifactId>
-      <exclusions>
-        <exclusion>
-          <groupId>log4j</groupId>
-          <artifactId>log4j</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <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>
-  </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/dependency-free-transaction-demo/hotel-reservation-service/src/main/java/org/apache/servicecomb/saga/demo/hotel/reservation/HotelReservationApplication.java b/saga-demo/dependency-free-transaction-demo/hotel-reservation-service/src/main/java/org/apache/servicecomb/saga/demo/hotel/reservation/HotelReservationApplication.java
deleted file mode 100644
index b6d3c01d..00000000
--- a/saga-demo/dependency-free-transaction-demo/hotel-reservation-service/src/main/java/org/apache/servicecomb/saga/demo/hotel/reservation/HotelReservationApplication.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.hotel.reservation;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-import io.servicecomb.springboot.starter.provider.EnableServiceComb;
-
-@SpringBootApplication
-@EnableServiceComb
-public class HotelReservationApplication {
-
-  public static void main(String[] args) {
-    SpringApplication.run(HotelReservationApplication.class, args);
-  }
-}
diff --git a/saga-demo/dependency-free-transaction-demo/hotel-reservation-service/src/main/java/org/apache/servicecomb/saga/demo/hotel/reservation/HotelReservationController.java b/saga-demo/dependency-free-transaction-demo/hotel-reservation-service/src/main/java/org/apache/servicecomb/saga/demo/hotel/reservation/HotelReservationController.java
deleted file mode 100644
index dfe00d87..00000000
--- a/saga-demo/dependency-free-transaction-demo/hotel-reservation-service/src/main/java/org/apache/servicecomb/saga/demo/hotel/reservation/HotelReservationController.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.hotel.reservation;
-
-import static java.util.Collections.singleton;
-import static javax.ws.rs.core.Response.Status.FORBIDDEN;
-import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE;
-import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE;
-import static org.springframework.web.bind.annotation.RequestMethod.POST;
-import static org.springframework.web.bind.annotation.RequestMethod.PUT;
-
-import java.util.Set;
-import java.util.UUID;
-
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestAttribute;
-import org.springframework.web.bind.annotation.RequestMapping;
-
-import io.servicecomb.provider.rest.common.RestSchema;
-import io.servicecomb.swagger.invocation.exception.InvocationException;
-import io.swagger.annotations.ApiResponse;
-import io.swagger.annotations.ApiResponses;
-
-@Controller
-@RequestMapping("/")
-@RestSchema(schemaId = "hotel-endpoint")
-public class HotelReservationController {
-
-  private final Set<String> customers = singleton("mike");
-
-  @ApiResponses({
-      @ApiResponse(code = 200, response = String.class, message = "authenticated user"),
-      @ApiResponse(code = 403, response = String.class, message = "unauthenticated user")
-  })
-  @RequestMapping(value = "reservations", method = POST, consumes = APPLICATION_FORM_URLENCODED_VALUE, produces = TEXT_PLAIN_VALUE)
-  public ResponseEntity<String> reserve(@RequestAttribute String customerId) {
-    if (!customers.contains(customerId)) {
-      throw new InvocationException(FORBIDDEN, "No such customer with id " + customerId);
-    }
-
-    return ResponseEntity.ok(String.format("{\n"
-            + "  \"body\": \"Hotel reserved with id %s for customer %s\"\n"
-            + "}",
-        UUID.randomUUID().toString(),
-        customerId));
-  }
-
-  @ApiResponses({
-      @ApiResponse(code = 200, response = String.class, message = "authenticated user"),
-      @ApiResponse(code = 403, response = String.class, message = "unauthenticated user")
-  })
-  @RequestMapping(value = "reservations", method = PUT, consumes = APPLICATION_FORM_URLENCODED_VALUE, produces = TEXT_PLAIN_VALUE)
-  public ResponseEntity<String> cancel(@RequestAttribute String customerId) {
-    if (!customers.contains(customerId)) {
-      throw new InvocationException(FORBIDDEN, "No such customer with id " + customerId);
-    }
-
-    return ResponseEntity.ok(String.format("Hotel reservation cancelled with id %s for customer %s",
-        UUID.randomUUID().toString(),
-        customerId));
-  }
-}
diff --git a/saga-demo/dependency-free-transaction-demo/hotel-reservation-service/src/main/resources/microservice.yaml b/saga-demo/dependency-free-transaction-demo/hotel-reservation-service/src/main/resources/microservice.yaml
deleted file mode 100644
index ea01a2a3..00000000
--- a/saga-demo/dependency-free-transaction-demo/hotel-reservation-service/src/main/resources/microservice.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-## ---------------------------------------------------------------------------
-## 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.
-## ---------------------------------------------------------------------------
-APPLICATION_ID: saga
-service_description:
-  name: hotel-reservation-service
-  version: 0.0.1
-cse:
-  service:
-    registry:
-      address: http://sc.servicecomb.io:30100
-  rest:
-    address: 0.0.0.0:8080
-  handler:
-    chain:
-      Consumer:
-        default: loadbalance
diff --git a/saga-demo/dependency-free-transaction-demo/payment-service/pom.xml b/saga-demo/dependency-free-transaction-demo/payment-service/pom.xml
deleted file mode 100644
index 045f324b..00000000
--- a/saga-demo/dependency-free-transaction-demo/payment-service/pom.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-<?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>dependency-free-transaction-demo</artifactId>
-    <groupId>org.apache.servicecomb.saga.demo</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>payment-service</artifactId>
-  <name>Saga::Demo::Dependency Free Transaction::Payment Service</name>
-
-
-  <dependencies>
-    <dependency>
-      <groupId>io.servicecomb</groupId>
-      <artifactId>spring-boot-starter-provider</artifactId>
-      <exclusions>
-        <exclusion>
-          <groupId>log4j</groupId>
-          <artifactId>log4j</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <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>
-  </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/dependency-free-transaction-demo/payment-service/src/main/java/org/apache/servicecomb/saga/demo/payment/PaymentApplication.java b/saga-demo/dependency-free-transaction-demo/payment-service/src/main/java/org/apache/servicecomb/saga/demo/payment/PaymentApplication.java
deleted file mode 100644
index 4395c22c..00000000
--- a/saga-demo/dependency-free-transaction-demo/payment-service/src/main/java/org/apache/servicecomb/saga/demo/payment/PaymentApplication.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.payment;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-import io.servicecomb.springboot.starter.provider.EnableServiceComb;
-
-@SpringBootApplication
-@EnableServiceComb
-public class PaymentApplication {
-
-  public static void main(String[] args) {
-    SpringApplication.run(PaymentApplication.class, args);
-  }
-}
diff --git a/saga-demo/dependency-free-transaction-demo/payment-service/src/main/java/org/apache/servicecomb/saga/demo/payment/PaymentController.java b/saga-demo/dependency-free-transaction-demo/payment-service/src/main/java/org/apache/servicecomb/saga/demo/payment/PaymentController.java
deleted file mode 100644
index cf1e7749..00000000
--- a/saga-demo/dependency-free-transaction-demo/payment-service/src/main/java/org/apache/servicecomb/saga/demo/payment/PaymentController.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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.payment;
-
-import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
-import static javax.ws.rs.core.Response.Status.FORBIDDEN;
-import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE;
-import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE;
-import static org.springframework.web.bind.annotation.RequestMethod.POST;
-import static org.springframework.web.bind.annotation.RequestMethod.PUT;
-
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestAttribute;
-import org.springframework.web.bind.annotation.RequestMapping;
-
-import io.servicecomb.provider.rest.common.RestSchema;
-import io.servicecomb.swagger.invocation.exception.InvocationException;
-import io.swagger.annotations.ApiResponse;
-import io.swagger.annotations.ApiResponses;
-
-@Controller
-@RequestMapping("/")
-@RestSchema(schemaId = "payment-endpoint")
-public class PaymentController {
-  private int balance = 1000;
-
-  @ApiResponses({
-      @ApiResponse(code = 200, response = String.class, message = "authenticated user"),
-      @ApiResponse(code = 403, response = String.class, message = "unauthenticated user"),
-      @ApiResponse(code = 400, response = String.class, message = "insufficient account balance")
-  })
-  @RequestMapping(value = "payments", method = POST, consumes = APPLICATION_FORM_URLENCODED_VALUE, produces = TEXT_PLAIN_VALUE)
-  public ResponseEntity<String> pay(@RequestAttribute String customerId) {
-    if ("anonymous".equals(customerId)) {
-      throw new InvocationException(FORBIDDEN, "No such customer with id " + customerId);
-    }
-
-    if (balance < 800) {
-      throw new InvocationException(BAD_REQUEST, "Not enough balance in account of customer " + customerId);
-    }
-
-    balance -= 800;
-    return ResponseEntity.ok(String.format("{\n"
-            + "  \"body\": \"Payment made for customer %s and remaining balance is %d\"\n"
-            + "}",
-        customerId,
-        balance));
-  }
-
-  @ApiResponses({
-      @ApiResponse(code = 200, response = String.class, message = "authenticated user"),
-      @ApiResponse(code = 403, response = String.class, message = "unauthenticated user")
-  })
-  @RequestMapping(value = "payments", method = PUT, consumes = APPLICATION_FORM_URLENCODED_VALUE, produces = TEXT_PLAIN_VALUE)
-  public ResponseEntity<String> refund(@RequestAttribute String customerId) {
-    if ("anonymous".equals(customerId)) {
-      throw new InvocationException(FORBIDDEN, "No such customer with id " + customerId);
-    }
-
-    balance += 800;
-    return ResponseEntity.ok(String.format("Payment refunded for customer %s and remaining balance is %d",
-        customerId,
-        balance));
-  }
-}
diff --git a/saga-demo/dependency-free-transaction-demo/payment-service/src/main/resources/microservice.yaml b/saga-demo/dependency-free-transaction-demo/payment-service/src/main/resources/microservice.yaml
deleted file mode 100644
index e520f9af..00000000
--- a/saga-demo/dependency-free-transaction-demo/payment-service/src/main/resources/microservice.yaml
+++ /dev/null
@@ -1,32 +0,0 @@
-## ---------------------------------------------------------------------------
-## 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.
-## ---------------------------------------------------------------------------
-APPLICATION_ID: saga-crossapp
-service_description:
-  name: payment-service
-  version: 0.0.1
-  properties:
-    allowCrossApp: true
-cse:
-  service:
-    registry:
-      address: http://sc.servicecomb.io:30100
-  rest:
-    address: 0.0.0.0:8080
-  handler:
-    chain:
-      Consumer:
-        default: loadbalance
diff --git a/saga-demo/dependency-free-transaction-demo/pom.xml b/saga-demo/dependency-free-transaction-demo/pom.xml
deleted file mode 100644
index 4765900f..00000000
--- a/saga-demo/dependency-free-transaction-demo/pom.xml
+++ /dev/null
@@ -1,67 +0,0 @@
-<?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>dependency-free-transaction-demo</artifactId>
-  <name>Saga::Demo::Dependency Free Transaction</name>
-  <packaging>pom</packaging>
-
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.apache.commons</groupId>
-        <artifactId>commons-lang3</artifactId>
-        <version>3.6</version>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb</groupId>
-        <artifactId>spring-boot-starter-provider</artifactId>
-        <version>${java.chassis.version}</version>
-        <exclusions>
-          <exclusion>
-            <groupId>com.google.code.findbugs</groupId>
-            <artifactId>annotations</artifactId>
-          </exclusion>
-        </exclusions>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb</groupId>
-        <artifactId>java-chassis-dependencies</artifactId>
-        <version>${java.chassis.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
-
-  <modules>
-    <module>car-rental-service</module>
-    <module>flight-booking-service</module>
-    <module>hotel-reservation-service</module>
-    <module>payment-service</module>
-    <module>demo-tests</module>
-  </modules>
-
-</project>
diff --git a/saga-demo/pom.xml b/saga-demo/pom.xml
index dfdef267..69bb1243 100644
--- a/saga-demo/pom.xml
+++ b/saga-demo/pom.xml
@@ -30,9 +30,7 @@
 
   <packaging>pom</packaging>
   <modules>
-    <module>dependency-free-transaction-demo</module>
-    <module>conditional-transaction-demo</module>
-    <module>pack-demo</module>
+    <module>booking</module>
   </modules>
 
   <dependencyManagement>
diff --git a/saga-discovery/pom.xml b/saga-discovery/pom.xml
deleted file mode 100644
index 676db618..00000000
--- a/saga-discovery/pom.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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</artifactId>
-    <groupId>org.apache.servicecomb.saga</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <groupId>org.apache.servicecomb.saga.discovery</groupId>
-  <artifactId>saga-discovery</artifactId>
-  <name>Saga::Discovery </name>
-
-  <packaging>pom</packaging>
-  <modules>
-    <module>saga-discovery-servicecenter</module>
-  </modules>
-
-
-</project>
diff --git a/saga-discovery/saga-discovery-servicecenter/pom.xml b/saga-discovery/saga-discovery-servicecenter/pom.xml
deleted file mode 100644
index 86787148..00000000
--- a/saga-discovery/saga-discovery-servicecenter/pom.xml
+++ /dev/null
@@ -1,124 +0,0 @@
-<?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-discovery</artifactId>
-    <groupId>org.apache.servicecomb.saga.discovery</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>saga-discovery-servicecenter</artifactId>
-  <name>Saga::Discovery::ServiceCenter</name>
-
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot-starter-test</artifactId>
-        <version>${spring.boot.version}</version>
-        <exclusions>
-          <exclusion>
-            <groupId>org.json</groupId>
-            <artifactId>json</artifactId>
-          </exclusion>
-        </exclusions>
-        <scope>test</scope>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb</groupId>
-        <artifactId>spring-boot-starter-provider</artifactId>
-        <version>${java.chassis.version}</version>
-        <exclusions>
-          <exclusion>
-            <groupId>com.google.code.findbugs</groupId>
-            <artifactId>annotations</artifactId>
-          </exclusion>
-        </exclusions>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb</groupId>
-        <artifactId>java-chassis-dependencies</artifactId>
-        <version>${java.chassis.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.servicecomb.saga</groupId>
-      <artifactId>saga-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.servicecomb.saga.transports</groupId>
-      <artifactId>transport-httpclient-spring</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.servicecomb.saga.transports</groupId>
-      <artifactId>transport-resttemplate</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.servicecomb</groupId>
-      <artifactId>spring-boot-starter-provider</artifactId>
-      <exclusions>
-        <exclusion>
-          <groupId>log4j</groupId>
-          <artifactId>log4j</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter</artifactId>
-      <exclusions>
-        <exclusion>
-          <groupId>ch.qos.logback</groupId>
-          <artifactId>*</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter-web</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter-test</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.hibernate</groupId>
-      <artifactId>hibernate-validator</artifactId>
-      <version>5.2.4.Final</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.github.seanyinx</groupId>
-      <artifactId>unit-scaffolding</artifactId>
-    </dependency>
-  </dependencies>
-</project>
diff --git a/saga-discovery/saga-discovery-servicecenter/src/main/java/org/apache/servicecomb/saga/discovery/service/center/ServiceCenterDiscoveryConfig.java b/saga-discovery/saga-discovery-servicecenter/src/main/java/org/apache/servicecomb/saga/discovery/service/center/ServiceCenterDiscoveryConfig.java
deleted file mode 100644
index 11110eff..00000000
--- a/saga-discovery/saga-discovery-servicecenter/src/main/java/org/apache/servicecomb/saga/discovery/service/center/ServiceCenterDiscoveryConfig.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.discovery.service.center;
-
-import org.springframework.boot.autoconfigure.AutoConfigureBefore;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Profile;
-
-import io.servicecomb.provider.springmvc.reference.RestTemplateBuilder;
-import org.apache.servicecomb.saga.transports.HttpClientTransportConfig;
-import org.apache.servicecomb.saga.transports.RestTransport;
-import org.apache.servicecomb.saga.transports.resttemplate.RestTemplateTransport;
-import io.servicecomb.springboot.starter.provider.EnableServiceComb;
-
-@EnableServiceComb
-@Profile("servicecomb")
-@Configuration
-@AutoConfigureBefore(HttpClientTransportConfig.class)
-public class ServiceCenterDiscoveryConfig {
-
-  static final String PROTOCOL = "cse://";
-
-  @Bean
-  RestTransport restTransport() {
-    return new RestTemplateTransport(RestTemplateBuilder.create(), PROTOCOL);
-  }
-}
diff --git a/saga-discovery/saga-discovery-servicecenter/src/main/resources/META-INF/spring.factories b/saga-discovery/saga-discovery-servicecenter/src/main/resources/META-INF/spring.factories
deleted file mode 100644
index b199c22a..00000000
--- a/saga-discovery/saga-discovery-servicecenter/src/main/resources/META-INF/spring.factories
+++ /dev/null
@@ -1,18 +0,0 @@
-## ---------------------------------------------------------------------------
-## 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.
-## ---------------------------------------------------------------------------
-org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-  org.apache.servicecomb.saga.discovery.service.center.ServiceCenterDiscoveryConfig
diff --git a/saga-discovery/saga-discovery-servicecenter/src/main/resources/microservice.yaml b/saga-discovery/saga-discovery-servicecenter/src/main/resources/microservice.yaml
deleted file mode 100644
index c183fc96..00000000
--- a/saga-discovery/saga-discovery-servicecenter/src/main/resources/microservice.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-## ---------------------------------------------------------------------------
-## 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.
-## ---------------------------------------------------------------------------
-APPLICATION_ID: saga
-service_description:
-  name: saga-service
-  version: 0.0.1
-cse:
-  service:
-    registry:
-      address: http://sc.servicecomb.io:30100
-  rest:
-    address: 0.0.0.0:8080
-  handler:
-    chain:
-      Consumer:
-        default: loadbalance
diff --git a/saga-discovery/saga-discovery-servicecenter/src/test/java/org/apache/servicecomb/saga/discovery/service/center/DummyController.java b/saga-discovery/saga-discovery-servicecenter/src/test/java/org/apache/servicecomb/saga/discovery/service/center/DummyController.java
deleted file mode 100644
index 710806d1..00000000
--- a/saga-discovery/saga-discovery-servicecenter/src/test/java/org/apache/servicecomb/saga/discovery/service/center/DummyController.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.discovery.service.center;
-
-import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE;
-import static org.springframework.web.bind.annotation.RequestMethod.GET;
-import static org.springframework.web.bind.annotation.RequestMethod.POST;
-import static org.springframework.web.bind.annotation.RequestMethod.PUT;
-
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestAttribute;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-
-import io.servicecomb.provider.rest.common.RestSchema;
-
-@Controller
-@RequestMapping("/rest")
-@RestSchema(schemaId = "dummy-rest-endpoint")
-public class DummyController {
-
-  @RequestMapping(value = "/usableResource", method = GET)
-  public ResponseEntity<String> getUseableResource(
-      @RequestParam(name = "foo") String foo,
-      @RequestParam(name = "hello") String who) {
-
-    return ResponseEntity.ok("foo " + foo + ", hello " + who);
-  }
-
-  @RequestMapping(value = "/usableResource", method = PUT)
-  public ResponseEntity<String> putUseableResource(@RequestParam(name = "foo") String foo, @RequestBody String json) {
-    return ResponseEntity.ok("foo " + foo + ", hello world" + json);
-  }
-
-  @RequestMapping(value = "/faultyResource", method = POST, consumes = APPLICATION_FORM_URLENCODED_VALUE)
-  public ResponseEntity<String> postFaultyResource(@RequestParam(name = "foo") String foo, @RequestAttribute(name = "hello") String hello) {
-    throw new RuntimeException("no such resource");
-  }
-}
diff --git a/saga-discovery/saga-discovery-servicecenter/src/test/java/org/apache/servicecomb/saga/discovery/service/center/ServiceCenterDiscoveryApplication.java b/saga-discovery/saga-discovery-servicecenter/src/test/java/org/apache/servicecomb/saga/discovery/service/center/ServiceCenterDiscoveryApplication.java
deleted file mode 100644
index 027b4418..00000000
--- a/saga-discovery/saga-discovery-servicecenter/src/test/java/org/apache/servicecomb/saga/discovery/service/center/ServiceCenterDiscoveryApplication.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.discovery.service.center;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-import io.servicecomb.springboot.starter.provider.EnableServiceComb;
-
-@SpringBootApplication
-@EnableServiceComb
-public class ServiceCenterDiscoveryApplication {
-
-  public static void main(String[] args) {
-    SpringApplication.run(ServiceCenterDiscoveryApplication.class, args);
-  }
-}
diff --git a/saga-discovery/saga-discovery-servicecenter/src/test/java/org/apache/servicecomb/saga/discovery/service/center/ServiceCenterDiscoveryRestTransportTest.java b/saga-discovery/saga-discovery-servicecenter/src/test/java/org/apache/servicecomb/saga/discovery/service/center/ServiceCenterDiscoveryRestTransportTest.java
deleted file mode 100644
index 6bfa7ae7..00000000
--- a/saga-discovery/saga-discovery-servicecenter/src/test/java/org/apache/servicecomb/saga/discovery/service/center/ServiceCenterDiscoveryRestTransportTest.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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.discovery.service.center;
-
-import static com.seanyinx.github.unit.scaffolding.AssertUtils.expectFailing;
-import static io.servicecomb.serviceregistry.client.LocalServiceRegistryClientImpl.LOCAL_REGISTRY_FILE_KEY;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonMap;
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
-
-import java.net.URL;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.apache.servicecomb.saga.transports.RestTransport;
-import org.apache.servicecomb.saga.transports.resttemplate.RestTemplateTransport;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import io.servicecomb.provider.springmvc.reference.RestTemplateBuilder;
-
-import org.apache.servicecomb.saga.core.TransportFailedException;
-
-@RunWith(SpringRunner.class)
-@SpringBootTest(classes = ServiceCenterDiscoveryApplication.class, webEnvironment = RANDOM_PORT)
-public class ServiceCenterDiscoveryRestTransportTest {
-
-  private static final String usableResource = "/rest/usableResource";
-  private static final String faultyResource = "/rest/faultyResource";
-  private static final String usableResponse = "foo bar, hello world";
-  private static final String json = "{\"hello\", \"world\"}";
-
-  private final RestTransport transport = new RestTemplateTransport(RestTemplateBuilder.create(), ServiceCenterDiscoveryConfig.PROTOCOL);
-  private final String serviceName = "saga-service";
-
-  @BeforeClass
-  public static void setUpClass() throws Exception {
-    setUpLocalRegistry();
-  }
-
-  private static void setUpLocalRegistry() {
-    ClassLoader loader = Thread.currentThread().getContextClassLoader();
-    URL resource = loader.getResource("registry.yaml");
-    System.setProperty(LOCAL_REGISTRY_FILE_KEY, resource.getPath());
-  }
-
-  @Test
-  public void sendsGetRequestToDiscoveredService() {
-    Map<String, Map<String, String>> requests = singletonMap("query", map("foo", "bar", "hello", "world"));
-    SagaResponse response = transport.with(serviceName, usableResource, "get", requests);
-
-    assertThat(response.succeeded(), is(true));
-    assertThat(response.body(), containsString(usableResponse));
-  }
-
-  @Test
-  public void putsRequestToDiscoveredService() {
-    Map<String, Map<String, String>> requests = new HashMap<>();
-    requests.put("query", singletonMap("foo", "bar"));
-    requests.put("json", singletonMap("body", json));
-
-    SagaResponse response = transport.with(serviceName, usableResource, "PUT", requests);
-
-    assertThat(response.succeeded(), is(true));
-    assertThat(response.body(), containsString(usableResponse + json));
-  }
-
-  @Test
-  public void blowsUpWhenRemoteResponseIsNot2XX() {
-    Map<String, Map<String, String>> requests = new HashMap<>();
-    requests.put("query", singletonMap("foo", "bar"));
-    requests.put("form", map("hello", "world"));
-
-    try {
-      transport.with(serviceName, faultyResource, "POST", requests);
-      expectFailing(TransportFailedException.class);
-    } catch (TransportFailedException e) {
-      assertThat(e.getMessage(), containsString("The remote service " + serviceName + " failed to serve"));
-    }
-  }
-
-  @Test
-  public void blowsUpWhenRemoteIsNotReachable() {
-    try {
-      transport.with("unknown-service", faultyResource, "DELETE", emptyMap());
-      expectFailing(TransportFailedException.class);
-    } catch (TransportFailedException e) {
-      assertThat(e.getMessage(), containsString("The remote service unknown-service failed to serve"));
-    }
-  }
-
-  @Test
-  public void blowsUpWhenMethodIsUnknown() {
-    try {
-      transport.with(serviceName, usableResource, "Blah", emptyMap());
-      expectFailing(TransportFailedException.class);
-    } catch (TransportFailedException e) {
-      assertThat(e.getCause().getMessage(), is("No such method Blah"));
-    }
-  }
-
-  private Map<String, String> map(String... pairs) {
-    return new LinkedHashMap<String, String>() {{
-      for (int i = 0; i < pairs.length; i += 2) {
-        put(pairs[i], pairs[i + 1]);
-      }
-    }};
-  }
-}
diff --git a/saga-discovery/saga-discovery-servicecenter/src/test/resources/log4j2-test.xml b/saga-discovery/saga-discovery-servicecenter/src/test/resources/log4j2-test.xml
deleted file mode 100644
index 58924c68..00000000
--- a/saga-discovery/saga-discovery-servicecenter/src/test/resources/log4j2-test.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?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>
-    <Root level="info">
-      <AppenderRef ref="Console"/>
-    </Root>
-  </Loggers>
-</Configuration>
diff --git a/saga-discovery/saga-discovery-servicecenter/src/test/resources/registry.yaml b/saga-discovery/saga-discovery-servicecenter/src/test/resources/registry.yaml
deleted file mode 100644
index 82752b44..00000000
--- a/saga-discovery/saga-discovery-servicecenter/src/test/resources/registry.yaml
+++ /dev/null
@@ -1,23 +0,0 @@
-## ---------------------------------------------------------------------------
-## 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.
-## ---------------------------------------------------------------------------
-saga-service:
-  - id: "001"
-    version: "0.0.1"
-    appid: saga
-    instances:
-      - endpoints:
-        - rest://127.0.0.1:8080?sslEnabled=false
diff --git a/saga-format/pom.xml b/saga-format/pom.xml
deleted file mode 100644
index a6c04578..00000000
--- a/saga-format/pom.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-<?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</artifactId>
-    <groupId>org.apache.servicecomb.saga</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>saga-format</artifactId>
-  <name>Saga::Format</name>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.servicecomb.saga</groupId>
-      <artifactId>saga-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-core</artifactId>
-      <version>${jackson.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-databind</artifactId>
-      <version>${jackson.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>io.kamon</groupId>
-      <artifactId>kamon-core_2.12</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.kamon</groupId>
-      <artifactId>kamon-annotation_2.12</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>org.hamcrest</groupId>
-      <artifactId>hamcrest-all</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>com.github.seanyinx</groupId>
-      <artifactId>unit-scaffolding</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-
-</project>
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/core/FailedSagaRequestContext.java b/saga-format/src/main/java/org/apache/servicecomb/saga/core/FailedSagaRequestContext.java
deleted file mode 100644
index 92d60392..00000000
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/core/FailedSagaRequestContext.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.core;
-
-import org.apache.servicecomb.saga.format.JsonFailedSagaResponse;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import org.apache.servicecomb.saga.format.JsonSagaRequest;
-
-public class FailedSagaRequestContext extends SagaRequestContext {
-
-  private final JsonSagaRequest request;
-
-  public FailedSagaRequestContext(
-      @JsonProperty("request") JsonSagaRequest request,
-      @JsonProperty("response") JsonFailedSagaResponse response) {
-    super(request, response);
-    this.request = request;
-  }
-
-  public JsonSagaRequest request() {
-    return request;
-  }
-}
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/core/JacksonToJsonFormat.java b/saga-format/src/main/java/org/apache/servicecomb/saga/core/JacksonToJsonFormat.java
deleted file mode 100644
index c00ce4a3..00000000
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/core/JacksonToJsonFormat.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.core;
-
-import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY;
-import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import kamon.annotation.EnableKamon;
-import kamon.annotation.Segment;
-
-@EnableKamon
-public class JacksonToJsonFormat implements ToJsonFormat {
-
-
-  private final ObjectMapper objectMapper = new ObjectMapper();
-
-  public JacksonToJsonFormat() {
-    objectMapper.setVisibility(
-        objectMapper.getSerializationConfig()
-            .getDefaultVisibilityChecker()
-            .withFieldVisibility(ANY)
-            .withGetterVisibility(NONE)
-            .withSetterVisibility(NONE)
-            .withCreatorVisibility(NONE));
-
-  }
-
-  @Segment(name = "toJson", category = "application", library = "kamon")
-  @Override
-  public String toJson(SagaRequest request) {
-    try {
-      return objectMapper.writeValueAsString(request);
-    } catch (JsonProcessingException e) {
-      throw new SagaException("Failed to serialize request to JSON: " + request, e);
-    }
-  }
-
-  @Segment(name = "toJson", category = "application", library = "kamon")
-  @Override
-  public String toJson(SagaRequest request, SagaResponse response) {
-    try {
-      return objectMapper.writeValueAsString(new SagaRequestContext(request, response));
-    } catch (JsonProcessingException e) {
-      throw new SagaException("Failed to serialize request & response to JSON: " + request + ", " + response, e);
-    }
-  }
-}
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/core/SagaRequestContext.java b/saga-format/src/main/java/org/apache/servicecomb/saga/core/SagaRequestContext.java
deleted file mode 100644
index 2e376172..00000000
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/core/SagaRequestContext.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.core;
-
-public class SagaRequestContext {
-
-  private final SagaRequest request;
-  private final SagaResponse response;
-
-  SagaRequestContext(SagaRequest request, SagaResponse response) {
-    this.request = request;
-    this.response = response;
-  }
-
-  public SagaRequest request() {
-    return request;
-  }
-
-  public SagaResponse response() {
-    return response;
-  }
-}
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/core/SuccessfulSagaRequestContext.java b/saga-format/src/main/java/org/apache/servicecomb/saga/core/SuccessfulSagaRequestContext.java
deleted file mode 100644
index f794a91e..00000000
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/core/SuccessfulSagaRequestContext.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.core;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import org.apache.servicecomb.saga.format.JsonSagaRequest;
-import org.apache.servicecomb.saga.format.JsonSuccessfulSagaResponse;
-
-public class SuccessfulSagaRequestContext extends SagaRequestContext {
-
-  private final JsonSagaRequest request;
-
-  @JsonCreator
-  public SuccessfulSagaRequestContext(
-      @JsonProperty("request") JsonSagaRequest request,
-      @JsonProperty("response") JsonSuccessfulSagaResponse response) {
-    super(request, response);
-    this.request = request;
-  }
-
-  public JsonSagaRequest request() {
-    return request;
-  }
-}
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/ChildrenExtractor.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/ChildrenExtractor.java
deleted file mode 100644
index cfd3b1c4..00000000
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/ChildrenExtractor.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.format;
-
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.servicecomb.saga.core.SagaException;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-import org.apache.servicecomb.saga.core.application.interpreter.FromJsonFormat;
-
-public class ChildrenExtractor implements FromJsonFormat<Set<String>> {
-
-  private static final String SAGA_CHILDREN = "sagaChildren";
-  private final ObjectMapper objectMapper = new ObjectMapper();
-
-  @Override
-  public Set<String> fromJson(String json) {
-    try {
-      return childrenOf(objectMapper.readValue(json, ObjectNode.class));
-    } catch (IOException e) {
-      throw new SagaException("Failed to deserialize json " + json, e);
-    }
-  }
-
-  private Set<String> childrenOf(ObjectNode value) {
-    Set<String> children = new HashSet<>();
-
-    if (value.has(SAGA_CHILDREN)) {
-      value.get(SAGA_CHILDREN)
-          .forEach(node -> children.add(node.textValue()));
-    }
-
-    return children;
-  }
-}
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonFallback.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonFallback.java
deleted file mode 100644
index 443ba66c..00000000
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonFallback.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.format;
-
-import org.apache.servicecomb.saga.core.Fallback;
-import org.apache.servicecomb.saga.core.Operation;
-import org.apache.servicecomb.saga.transports.TransportFactory;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonSubTypes;
-import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
-import com.fasterxml.jackson.annotation.JsonTypeInfo;
-
-import org.apache.servicecomb.saga.format.JacksonFallback.NopJacksonFallback;
-
-@JsonTypeInfo(
-    use = JsonTypeInfo.Id.NAME,
-    include = JsonTypeInfo.As.PROPERTY,
-    visible = true,
-    property = "type")
-@JsonSubTypes({
-    @Type(value = JacksonRestFallback.class, name = Operation.TYPE_REST),
-    @Type(value = NopJacksonFallback.class, name = Operation.TYPE_NOP)
-})
-public interface JacksonFallback extends Fallback, TransportAware {
-
-  JacksonFallback NOP_TRANSPORT_AWARE_FALLBACK = new NopJacksonFallback(TYPE_NOP);
-
-  class NopJacksonFallback implements JacksonFallback {
-
-    private final String type;
-
-    @JsonCreator
-    public NopJacksonFallback(@JsonProperty("type") String type) {
-      this.type = type;
-    }
-
-    @Override
-    public String type() {
-      return type;
-    }
-
-    @Override
-    public Operation with(TransportFactory transport) {
-      return this;
-    }
-  }
-}
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonFromJsonFormat.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonFromJsonFormat.java
deleted file mode 100644
index c26a82f2..00000000
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonFromJsonFormat.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.format;
-
-import java.io.IOException;
-
-import org.apache.servicecomb.saga.transports.TransportFactory;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import org.apache.servicecomb.saga.core.SagaDefinition;
-import org.apache.servicecomb.saga.core.SagaException;
-import org.apache.servicecomb.saga.core.application.interpreter.FromJsonFormat;
-
-import kamon.annotation.EnableKamon;
-import kamon.annotation.Segment;
-
-@EnableKamon
-public class JacksonFromJsonFormat implements FromJsonFormat<SagaDefinition> {
-
-  private final ObjectMapper objectMapper = new ObjectMapper();
-  private final TransportFactory transportFactory;
-
-  public JacksonFromJsonFormat(TransportFactory transportFactory) {
-    this.transportFactory = transportFactory;
-  }
-
-  @Segment(name = "fromJson", category = "application", library = "kamon")
-  @Override
-  public SagaDefinition fromJson(String requestJson) {
-    try {
-      JsonSagaDefinition definition = objectMapper.readValue(requestJson, JsonSagaDefinition.class);
-
-      for (JsonSagaRequest request : definition.requests()) {
-        request.with(transportFactory);
-      }
-
-      return definition;
-    } catch (IOException e) {
-      throw new SagaException("Failed to interpret JSON " + requestJson, e);
-    }
-  }
-}
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestCompensation.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestCompensation.java
deleted file mode 100644
index 1837563e..00000000
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestCompensation.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.format;
-
-import java.util.Map;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import org.apache.servicecomb.saga.core.Compensation;
-
-public class JacksonRestCompensation extends JacksonRestOperation implements Compensation {
-
-  private final int retries;
-
-  public JacksonRestCompensation(
-    String path,
-    String method,
-    Map<String, Map<String, String>> params) {
-    this(DEFAULT_RETRIES, path, method, params);
-  }
-
-  @JsonCreator
-  public JacksonRestCompensation(
-      @JsonProperty("retries") int retries,
-      @JsonProperty("path") String path,
-      @JsonProperty("method") String method,
-      @JsonProperty("params") Map<String, Map<String, String>> params) {
-    super(path, method, params);
-    this.retries = retries <= 0? DEFAULT_RETRIES : retries;
-  }
-
-  @Override
-  public int retries() {
-    return retries;
-  }
-}
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestFallback.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestFallback.java
deleted file mode 100644
index 35c54fe3..00000000
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestFallback.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.format;
-
-import java.util.Map;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-class JacksonRestFallback extends JacksonRestOperation implements JacksonFallback {
-
-  private final String type;
-
-  @JsonCreator
-  public JacksonRestFallback(
-      @JsonProperty("type") String type,
-      @JsonProperty("path") String path,
-      @JsonProperty("method") String method,
-      @JsonProperty("params") Map<String, Map<String, String>> params) {
-    super(path, method, params);
-    this.type = type;
-  }
-
-  @Override
-  public String type() {
-    return type;
-  }
-}
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestOperation.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestOperation.java
deleted file mode 100644
index 4d424517..00000000
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestOperation.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.format;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.servicecomb.saga.transports.TransportFactory;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-
-import org.apache.servicecomb.saga.core.RestOperation;
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.apache.servicecomb.saga.transports.RestTransport;
-
-class JacksonRestOperation extends RestOperation implements TransportAware {
-
-  @JsonIgnore
-  private RestTransport transport;
-
-  JacksonRestOperation(String path, String method, Map<String, Map<String, String>> params) {
-    super(path, method, params);
-  }
-
-  @Override
-  public JacksonRestOperation with(TransportFactory transport) {
-    this.transport = transport.restTransport();
-    return this;
-  }
-
-  @Override
-  public SagaResponse send(String address) {
-    return transport.with(address, path(), method(), params());
-  }
-
-  @Override
-  public SagaResponse send(String address, SagaResponse response) {
-    Map<String, Map<String, String>> updated = new HashMap<>(params());
-    updated.computeIfAbsent("form", (key) -> new HashMap<>()).put("response", response.body());
-
-    return transport.with(
-        address,
-        path(),
-        method(),
-        updated);
-  }
-}
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestTransaction.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestTransaction.java
deleted file mode 100644
index 4ea6d8c9..00000000
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonRestTransaction.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.format;
-
-import java.util.Map;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import org.apache.servicecomb.saga.core.Transaction;
-
-public class JacksonRestTransaction extends JacksonRestOperation implements Transaction {
-
-  @JsonCreator
-  public JacksonRestTransaction(
-      @JsonProperty("path") String path,
-      @JsonProperty("method") String method,
-      @JsonProperty("params") Map<String, Map<String, String>> params) {
-    super(path, method, params);
-  }
-}
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonSagaEventFormat.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonSagaEventFormat.java
deleted file mode 100644
index 1b416aaf..00000000
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JacksonSagaEventFormat.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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.format;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.BiFunction;
-
-import org.apache.servicecomb.saga.core.FailedSagaRequestContext;
-import org.apache.servicecomb.saga.core.NoOpSagaRequest;
-import org.apache.servicecomb.saga.core.SagaEvent;
-import org.apache.servicecomb.saga.core.SagaException;
-import org.apache.servicecomb.saga.core.SagaStartedEvent;
-import org.apache.servicecomb.saga.core.SuccessfulSagaRequestContext;
-import org.apache.servicecomb.saga.core.TransactionAbortedEvent;
-import org.apache.servicecomb.saga.core.TransactionCompensatedEvent;
-import org.apache.servicecomb.saga.core.TransactionStartedEvent;
-import org.apache.servicecomb.saga.transports.TransportFactory;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import org.apache.servicecomb.saga.core.SagaEndedEvent;
-import org.apache.servicecomb.saga.core.TransactionEndedEvent;
-
-public class JacksonSagaEventFormat implements SagaEventFormat {
-  private final Map<String, BiFunction<String, String, SagaEvent>> eventFactories = new HashMap<String, BiFunction<String, String, SagaEvent>>() {{
-    put(SagaStartedEvent.class.getSimpleName(), (sagaId, json) -> sagaStartedEvent(sagaId, json));
-    put(TransactionStartedEvent.class.getSimpleName(), (sagaId, json) -> transactionStartedEvent(sagaId, json));
-    put(TransactionEndedEvent.class.getSimpleName(), (sagaId, json) -> transactionEndedEvent(sagaId, json));
-    put(TransactionAbortedEvent.class.getSimpleName(), (sagaId, json) -> transactionAbortedEvent(sagaId, json));
-    put(TransactionCompensatedEvent.class.getSimpleName(), (sagaId, json) -> compensationEndedEvent(sagaId, json));
-    put(SagaEndedEvent.class.getSimpleName(), (sagaId, json) -> sagaEndedEvent(sagaId));
-  }};
-
-  private final ObjectMapper objectMapper = new ObjectMapper();
-  private final TransportFactory transportFactory;
-
-  public JacksonSagaEventFormat(TransportFactory transportFactory) {
-    this.transportFactory = transportFactory;
-  }
-
-  @Override
-  public SagaEvent toSagaEvent(String sagaId, String eventType, String contentJson) {
-    return eventFactories.get(eventType).apply(sagaId, contentJson);
-  }
-
-  private SagaEvent sagaStartedEvent(String sagaId, String json) {
-    return new SagaStartedEvent(
-        sagaId,
-        json,
-        NoOpSagaRequest.SAGA_START_REQUEST);
-  }
-
-  private SagaEvent transactionStartedEvent(String sagaId, String json) {
-    try {
-      return new TransactionStartedEvent(sagaId, objectMapper.readValue(json, JsonSagaRequest.class).with(transportFactory));
-    } catch (IOException e) {
-      throw new SagaException(cause(sagaId, json), e);
-    }
-  }
-
-  private SagaEvent transactionEndedEvent(String sagaId, String json) {
-    try {
-      SuccessfulSagaRequestContext context = objectMapper.readValue(json, SuccessfulSagaRequestContext.class);
-      return new TransactionEndedEvent(sagaId, context.request().with(transportFactory), context.response());
-    } catch (IOException e) {
-      throw new SagaException(cause(sagaId, json), e);
-    }
-  }
-
-  private SagaEvent transactionAbortedEvent(String sagaId, String json) {
-    try {
-      FailedSagaRequestContext context = objectMapper.readValue(json, FailedSagaRequestContext.class);
-      return new TransactionAbortedEvent(sagaId, context.request().with(transportFactory), context.response());
-    } catch (IOException e) {
-      throw new SagaException(cause(sagaId, json), e);
-    }
-  }
-
-  private SagaEvent compensationEndedEvent(String sagaId, String json) {
-    try {
-      SuccessfulSagaRequestContext context = objectMapper.readValue(json, SuccessfulSagaRequestContext.class);
-      return new TransactionCompensatedEvent(sagaId, context.request().with(transportFactory), context.response());
-    } catch (IOException e) {
-      throw new SagaException(cause(sagaId, json), e);
-    }
-  }
-
-  private SagaEvent sagaEndedEvent(String sagaId) {
-    return new SagaEndedEvent(
-        sagaId,
-        NoOpSagaRequest.SAGA_END_REQUEST);
-  }
-
-  private String cause(String sagaId, String json) {
-    return "Failed to deserialize saga event of sage id: " + sagaId + " from json: " + json;
-  }
-}
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JsonFailedSagaResponse.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JsonFailedSagaResponse.java
deleted file mode 100644
index 16ada6ef..00000000
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JsonFailedSagaResponse.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.format;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import org.apache.servicecomb.saga.core.FailedSagaResponse;
-
-public class JsonFailedSagaResponse extends FailedSagaResponse {
-
-  public JsonFailedSagaResponse(@JsonProperty("body") String body) {
-    super(body);
-  }
-}
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JsonRestSagaRequest.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JsonRestSagaRequest.java
deleted file mode 100644
index 9660eb4e..00000000
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JsonRestSagaRequest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.format;
-
-import static org.apache.servicecomb.saga.format.JacksonFallback.NOP_TRANSPORT_AWARE_FALLBACK;
-
-import org.apache.servicecomb.saga.core.SagaRequestImpl;
-import org.apache.servicecomb.saga.transports.TransportFactory;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import org.apache.servicecomb.saga.core.Operation;
-
-public class JsonRestSagaRequest extends SagaRequestImpl implements JsonSagaRequest {
-
-  private final JacksonRestTransaction transaction;
-  private final JacksonRestCompensation compensation;
-  private final JacksonFallback fallback;
-
-  @JsonCreator
-  public JsonRestSagaRequest(
-      @JsonProperty("id") String id,
-      @JsonProperty("serviceName") String serviceName,
-      @JsonProperty("type") String type,
-      @JsonProperty("transaction") JacksonRestTransaction transaction,
-      @JsonProperty("compensation") JacksonRestCompensation compensation,
-      @JsonProperty("fallback") JacksonFallback fallback,
-      @JsonProperty("parents") String[] parents,
-      @JsonProperty("failRetryDelayMilliseconds") int failRetryDelayMilliseconds) {
-
-    super(id, serviceName, type, transaction, compensation,
-        fallback == null ? NOP_TRANSPORT_AWARE_FALLBACK : fallback,
-        parents, failRetryDelayMilliseconds);
-
-    checkNull(transaction, "transaction");
-    checkNull(compensation, "compensation");
-
-    this.transaction = transaction;
-    this.compensation = compensation;
-    this.fallback = fallback == null ? NOP_TRANSPORT_AWARE_FALLBACK : fallback;
-  }
-
-  @Override
-  public JsonSagaRequest with(TransportFactory transportFactory) {
-    transaction.with(transportFactory);
-    compensation.with(transportFactory);
-    fallback.with(transportFactory);
-    return this;
-  }
-
-  private void checkNull(Operation operation, String operationName) {
-    if (operation == null) {
-      throw new IllegalArgumentException("Invalid request with NO " + operationName + " specified");
-    }
-  }
-}
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JsonSagaDefinition.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JsonSagaDefinition.java
deleted file mode 100644
index 5293a130..00000000
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JsonSagaDefinition.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.format;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.servicecomb.saga.core.ForwardRecovery;
-import org.apache.servicecomb.saga.core.RecoveryPolicy;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import org.apache.servicecomb.saga.core.BackwardRecovery;
-import org.apache.servicecomb.saga.core.SagaDefinition;
-
-class JsonSagaDefinition implements SagaDefinition {
-
-  static final RecoveryPolicy backwardRecovery = new BackwardRecovery();
-
-  private static final Map<String, RecoveryPolicy> policies = new HashMap<String, RecoveryPolicy>(){{
-    put(RecoveryPolicy.SAGA_BACKWARD_RECOVERY_POLICY, backwardRecovery);
-    put(RecoveryPolicy.SAGA_FORWARD_RECOVERY_POLICY, new ForwardRecovery());
-  }};
-
-  private final JsonSagaRequest[] requests;
-  private final RecoveryPolicy policy;
-
-  public JsonSagaDefinition(
-      @JsonProperty("policy") String policy,
-      @JsonProperty("requests") JsonSagaRequest[] requests) {
-
-    this.requests = requests;
-    this.policy = policies.getOrDefault(policy, backwardRecovery);
-  }
-
-  @Override
-  public RecoveryPolicy policy() {
-    return policy;
-  }
-
-  @Override
-  public JsonSagaRequest[] requests() {
-    return requests;
-  }
-}
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JsonSagaRequest.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JsonSagaRequest.java
deleted file mode 100644
index 45d39810..00000000
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JsonSagaRequest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.format;
-
-import org.apache.servicecomb.saga.core.Operation;
-import org.apache.servicecomb.saga.core.SagaRequest;
-import org.apache.servicecomb.saga.transports.TransportFactory;
-
-import com.fasterxml.jackson.annotation.JsonSubTypes;
-import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
-import com.fasterxml.jackson.annotation.JsonTypeInfo;
-
-@JsonTypeInfo(
-    use = JsonTypeInfo.Id.NAME,
-    include = JsonTypeInfo.As.PROPERTY,
-    visible = true,
-    property = "type")
-@JsonSubTypes({
-    @Type(value = JsonRestSagaRequest.class, name = Operation.TYPE_REST)
-})
-public interface JsonSagaRequest extends SagaRequest {
-
-  JsonSagaRequest with(TransportFactory transportFactory);
-}
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JsonSuccessfulSagaResponse.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/JsonSuccessfulSagaResponse.java
deleted file mode 100644
index 273fc3d6..00000000
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/JsonSuccessfulSagaResponse.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.format;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import org.apache.servicecomb.saga.core.SuccessfulSagaResponse;
-
-public class JsonSuccessfulSagaResponse extends SuccessfulSagaResponse {
-
-  public JsonSuccessfulSagaResponse(@JsonProperty("body") String body) {
-    super(body);
-  }
-
-}
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/SagaEventFormat.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/SagaEventFormat.java
deleted file mode 100644
index d035e96d..00000000
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/SagaEventFormat.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.format;
-
-import org.apache.servicecomb.saga.core.SagaEvent;
-
-public interface SagaEventFormat {
-
-  SagaEvent toSagaEvent(String sagaId, String eventType, String contentJson);
-}
diff --git a/saga-format/src/main/java/org/apache/servicecomb/saga/format/TransportAware.java b/saga-format/src/main/java/org/apache/servicecomb/saga/format/TransportAware.java
deleted file mode 100644
index edcabf7d..00000000
--- a/saga-format/src/main/java/org/apache/servicecomb/saga/format/TransportAware.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.format;
-
-import org.apache.servicecomb.saga.transports.TransportFactory;
-import org.apache.servicecomb.saga.core.Operation;
-
-interface TransportAware {
-
-  Operation with(TransportFactory transport);
-}
diff --git a/saga-format/src/test/java/org/apache/servicecomb/saga/format/ChildrenExtractorTest.java b/saga-format/src/test/java/org/apache/servicecomb/saga/format/ChildrenExtractorTest.java
deleted file mode 100644
index 1dad3613..00000000
--- a/saga-format/src/test/java/org/apache/servicecomb/saga/format/ChildrenExtractorTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.format;
-
-import static com.seanyinx.github.unit.scaffolding.AssertUtils.expectFailing;
-import static org.hamcrest.Matchers.containsInAnyOrder;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-
-import java.util.Set;
-
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.junit.Test;
-
-import org.apache.servicecomb.saga.core.SagaException;
-
-public class ChildrenExtractorTest {
-
-  private static final String json = "{\n"
-      + "  \"foo\": \"bar\",\n"
-      + "  \"sagaChildren\": [\n"
-      + "    \"id1\",\n"
-      + "    \"id2\",\n"
-      + "    \"id3\"\n"
-      + "  ]\n"
-      + "}";
-
-  private final ChildrenExtractor extractor = new ChildrenExtractor();
-
-  @Test
-  public void extractsChildrenIdFromJson() throws Exception {
-    Set<String> children = extractor.fromJson(json);
-
-    assertThat(children, containsInAnyOrder("id1", "id2", "id3"));
-  }
-
-  @Test
-  public void emptyChildrenIfNoSuchField() throws Exception {
-    Set<String> children = extractor.fromJson("{}");
-
-    assertThat(children.isEmpty(), is(true));
-  }
-
-  @Test
-  public void emptyChildrenIfNoneResponse() throws Exception {
-    Set<String> children = extractor.fromJson(SagaResponse.NONE_RESPONSE.body());
-
-    assertThat(children, containsInAnyOrder("none"));
-  }
-
-  @Test
-  public void blowsUpWithInvalidJson() throws Exception {
-    try {
-      extractor.fromJson("blah");
-      expectFailing(SagaException.class);
-    } catch (SagaException e) {
-      assertThat(e.getMessage(), is("Failed to deserialize json blah"));
-    }
-  }
-}
diff --git a/saga-format/src/test/java/org/apache/servicecomb/saga/format/JacksonFromJsonFormatTest.java b/saga-format/src/test/java/org/apache/servicecomb/saga/format/JacksonFromJsonFormatTest.java
deleted file mode 100644
index bbf7510f..00000000
--- a/saga-format/src/test/java/org/apache/servicecomb/saga/format/JacksonFromJsonFormatTest.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * 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.format;
-
-import static com.seanyinx.github.unit.scaffolding.Randomness.uniquify;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonMap;
-import static org.hamcrest.Matchers.contains;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.when;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-import org.apache.servicecomb.saga.core.Operation;
-import org.apache.servicecomb.saga.core.SagaException;
-import org.apache.servicecomb.saga.core.SagaRequest;
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.apache.servicecomb.saga.core.SuccessfulSagaResponse;
-import org.apache.servicecomb.saga.core.application.interpreter.FromJsonFormat;
-import org.apache.servicecomb.saga.transports.RestTransport;
-import org.apache.servicecomb.saga.transports.TransportFactory;
-import org.hamcrest.Matchers;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import com.seanyinx.github.unit.scaffolding.AssertUtils;
-
-import org.apache.servicecomb.saga.core.SagaDefinition;
-
-public class JacksonFromJsonFormatTest {
-
-  private static final String requests = "{\n"
-      + "  \"requests\": [\n"
-      + "    {\n"
-      + "      \"id\": \"request-aaa\",\n"
-      + "      \"type\": \"rest\",\n"
-      + "      \"serviceName\": \"aaa\",\n"
-      + "      \"transaction\": {\n"
-      + "        \"method\": \"post\",\n"
-      + "        \"path\": \"/rest/as\",\n"
-      + "        \"params\": {\n"
-      + "          \"form\": {\n"
-      + "            \"foo\": \"as\"\n"
-      + "          }\n"
-      + "        }\n"
-      + "      },\n"
-      + "      \"compensation\": {\n"
-      + "        \"method\": \"delete\",\n"
-      + "        \"path\": \"/rest/as\",\n"
-      + "        \"params\": {\n"
-      + "          \"query\": {\n"
-      + "            \"bar\": \"as\"\n"
-      + "          }\n"
-      + "        }\n"
-      + "      },\n"
-      + "      \"fallback\": {\n"
-      + "        \"type\": \"rest\",\n"
-      + "        \"method\":\"put\",\n"
-      + "        \"path\": \"/rest/as\"\n"
-      + "      }\n"
-      + "    },\n"
-      + "    {\n"
-      + "      \"id\": \"request-bbb\",\n"
-      + "      \"type\": \"rest\",\n"
-      + "      \"serviceName\": \"bbb\",\n"
-      + "      \"transaction\": {\n"
-      + "        \"method\": \"post\",\n"
-      + "        \"path\": \"/rest/bs\",\n"
-      + "        \"params\": {\n"
-      + "          \"query\": {\n"
-      + "            \"foo\": \"bs\"\n"
-      + "          },\n"
-      + "          \"json\": {\n"
-      + "            \"body\": \"{ \\\"bar\\\": \\\"bs\\\" }\"\n"
-      + "          }\n"
-      + "        }\n"
-      + "      },\n"
-      + "      \"compensation\": {\n"
-      + "        \"retries\": 4,\n"
-      + "        \"method\": \"delete\",\n"
-      + "        \"path\": \"/rest/bs\"\n"
-      + "      },\n"
-      + "      \"fallback\": {\n"
-      + "        \"type\": \"rest\",\n"
-      + "        \"method\":\"put\",\n"
-      + "        \"path\": \"/rest/bs\"\n"
-      + "      }\n"
-      + "    },\n"
-      + "    {\n"
-      + "      \"id\": \"request-ccc\",\n"
-      + "      \"type\": \"rest\",\n"
-      + "      \"serviceName\": \"ccc\",\n"
-      + "      \"parents\": [\n"
-      + "        \"request-aaa\",\n"
-      + "        \"request-bbb\"\n"
-      + "      ],\n"
-      + "      \"transaction\": {\n"
-      + "        \"method\": \"post\",\n"
-      + "        \"path\": \"/rest/cs\",\n"
-      + "        \"params\": {\n"
-      + "          \"query\": {\n"
-      + "            \"foo\": \"cs\"\n"
-      + "          },\n"
-      + "          \"form\": {\n"
-      + "            \"bar\": \"cs\"\n"
-      + "          }\n"
-      + "        }\n"
-      + "      },\n"
-      + "      \"compensation\": {\n"
-      + "        \"retries\": 5,\n"
-      + "        \"method\": \"delete\",\n"
-      + "        \"path\": \"/rest/cs\"\n"
-      + "      },\n"
-      + "      \"fallback\": {\n"
-      + "        \"type\": \"rest\",\n"
-      + "        \"method\":\"put\",\n"
-      + "        \"path\": \"/rest/cs\"\n"
-      + "      }\n"
-      + "    }\n"
-      + "  ]\n"
-      + "}\n";
-
-  private final SagaResponse response11 = new SuccessfulSagaResponse(uniquify("response11"));
-  private final SagaResponse response12 = new SuccessfulSagaResponse(uniquify("response12"));
-  private final SagaResponse response13 = new SuccessfulSagaResponse(uniquify("response13"));
-  private final SagaResponse response21 = new SuccessfulSagaResponse(uniquify("response21"));
-  private final SagaResponse response22 = new SuccessfulSagaResponse(uniquify("response22"));
-  private final SagaResponse response23 = new SuccessfulSagaResponse(uniquify("response23"));
-  private final SagaResponse response31 = new SuccessfulSagaResponse(uniquify("response31"));
-  private final SagaResponse response32 = new SuccessfulSagaResponse(uniquify("response32"));
-  private final SagaResponse response33 = new SuccessfulSagaResponse(uniquify("response33"));
-
-  private final RestTransport restTransport = Mockito.mock(RestTransport.class);
-  private final TransportFactory transportFactory = Mockito.mock(TransportFactory.class);
-  private final FromJsonFormat<SagaDefinition> format = new JacksonFromJsonFormat(transportFactory);
-
-  @Before
-  public void setUp() throws Exception {
-    when(transportFactory.restTransport()).thenReturn(restTransport);
-
-    when(restTransport.with("aaa", "/rest/as", "post", singletonMap("form", singletonMap("foo", "as"))))
-        .thenReturn(response11);
-    when(restTransport.with("aaa", "/rest/as", "delete", singletonMap("query", singletonMap("bar", "as"))))
-        .thenReturn(response12);
-    when(restTransport.with("aaa", "/rest/as", "put", emptyMap()))
-        .thenReturn(response13);
-
-    when(restTransport
-        .with("bbb", "/rest/bs", "post", mapOf("query", singletonMap("foo", "bs"), "json", singletonMap("body", "{ \"bar\": \"bs\" }"))))
-        .thenReturn(response21);
-    when(restTransport.with("bbb", "/rest/bs", "delete", emptyMap()))
-        .thenReturn(response22);
-    when(restTransport.with("bbb", "/rest/bs", "put", emptyMap()))
-        .thenReturn(response23);
-
-    when(restTransport
-        .with("ccc", "/rest/cs", "post", mapOf("query", singletonMap("foo", "cs"), "form", singletonMap("bar", "cs"))))
-        .thenReturn(response31);
-    when(restTransport.with("ccc", "/rest/cs", "delete", emptyMap()))
-        .thenReturn(response32);
-    when(restTransport.with("ccc", "/rest/cs", "put", emptyMap()))
-        .thenReturn(response33);
-  }
-
-  @Test
-  public void addTransportToDeserializedRequests() throws IOException {
-    SagaRequest[] sagaRequests = format.fromJson(requests).requests();
-
-    assertThat(collect(sagaRequests, SagaRequest::id), contains("request-aaa", "request-bbb", "request-ccc"));
-    assertThat(collect(sagaRequests, SagaRequest::serviceName), contains("aaa", "bbb", "ccc"));
-    assertThat(collect(sagaRequests, SagaRequest::type), Matchers
-        .contains(Operation.TYPE_REST, Operation.TYPE_REST, Operation.TYPE_REST));
-    assertThat(collect(sagaRequests, (request) -> request.compensation().retries()), contains(3, 4, 5));
-    assertThat(collect(sagaRequests, (request) -> request.fallback().type()), Matchers
-        .contains(Operation.TYPE_REST, Operation.TYPE_REST, Operation.TYPE_REST));
-
-    SagaResponse response = sagaRequests[0].transaction().send("aaa");
-    assertThat(response, is(response11));
-
-    response = sagaRequests[0].compensation().send("aaa");
-    assertThat(response, is(response12));
-
-    response = sagaRequests[0].fallback().send("aaa");
-    assertThat(response, is(response13));
-    assertThat(sagaRequests[0].parents().length, is(0));
-
-    response = sagaRequests[1].transaction().send("bbb");
-    assertThat(response, is(response21));
-
-    response = sagaRequests[1].compensation().send("bbb");
-    assertThat(response, is(response22));
-
-    response = sagaRequests[1].fallback().send("bbb");
-    assertThat(response, is(response23));
-    assertThat(sagaRequests[1].parents().length, is(0));
-
-    response = sagaRequests[2].transaction().send("ccc");
-    assertThat(response, is(response31));
-
-    response = sagaRequests[2].compensation().send("ccc");
-    assertThat(response, is(response32));
-
-    response = sagaRequests[2].fallback().send("ccc");
-    assertThat(response, is(response33));
-    assertArrayEquals(new String[]{"request-aaa", "request-bbb"}, sagaRequests[2].parents());
-  }
-
-  @Test
-  public void blowsUpWhenJsonIsInvalid() throws IOException {
-    String invalidRequest = "invalid-json";
-
-    try {
-      format.fromJson(invalidRequest);
-      AssertUtils.expectFailing(SagaException.class);
-    } catch (SagaException e) {
-      assertThat(e.getMessage(), is("Failed to interpret JSON invalid-json"));
-    }
-  }
-
-  private <T> Collection<T> collect(SagaRequest[] requests, Function<SagaRequest, T> mapper) {
-    return Arrays.stream(requests)
-        .map(mapper)
-        .collect(Collectors.toList());
-  }
-
-  private Map<String, Map<String, String>> mapOf(
-      String key1,
-      Map<String, String> value1,
-      String key2,
-      Map<String, String> value2) {
-
-    Map<String, Map<String, String>> map = new HashMap<>();
-    map.put(key1, value1);
-    map.put(key2, value2);
-    return map;
-  }
-}
diff --git a/saga-format/src/test/java/org/apache/servicecomb/saga/format/JacksonRestOperationTest.java b/saga-format/src/test/java/org/apache/servicecomb/saga/format/JacksonRestOperationTest.java
deleted file mode 100644
index 5c890a66..00000000
--- a/saga-format/src/test/java/org/apache/servicecomb/saga/format/JacksonRestOperationTest.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.format;
-
-import static com.seanyinx.github.unit.scaffolding.Randomness.uniquify;
-import static java.util.Collections.emptyMap;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.when;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.servicecomb.saga.core.Operation;
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.apache.servicecomb.saga.transports.RestTransport;
-import org.hamcrest.core.Is;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mockito;
-
-@SuppressWarnings("unchecked")
-public class JacksonRestOperationTest {
-
-  private final String address = uniquify("address");
-  private final String path = uniquify("path");
-  private final String method = "PUT";
-  private final Map<String, Map<String, String>> params = new HashMap<>();
-
-  private final RestTransport transport = Mockito.mock(RestTransport.class);
-  private final JacksonRestOperation restOperation = new JacksonRestOperation(path, method, params);
-
-  @Before
-  public void setUp() throws Exception {
-    restOperation.with(() -> transport);
-  }
-
-  @Test
-  public void appendsResponseToForm() throws Exception {
-    ArgumentCaptor<Map> argumentCaptor = ArgumentCaptor.forClass(Map.class);
-    when(transport.with(eq(address), eq(path), eq(method), argumentCaptor.capture())).thenReturn(
-        SagaResponse.EMPTY_RESPONSE);
-
-    SagaResponse response = restOperation.send(address, Operation.SUCCESSFUL_SAGA_RESPONSE);
-
-    assertThat(response, Is.is(SagaResponse.EMPTY_RESPONSE));
-
-    Map<String, Map<String, String>> updatedParams = argumentCaptor.getValue();
-    assertThat(updatedParams.getOrDefault("form", emptyMap()).get("response"), Is.is(Operation.SUCCESSFUL_SAGA_RESPONSE.body()));
-    assertThat(params.isEmpty(), is(true));
-  }
-}
diff --git a/saga-format/src/test/java/org/apache/servicecomb/saga/format/JsonRestSagaRequestTest.java b/saga-format/src/test/java/org/apache/servicecomb/saga/format/JsonRestSagaRequestTest.java
deleted file mode 100644
index 7c0896d5..00000000
--- a/saga-format/src/test/java/org/apache/servicecomb/saga/format/JsonRestSagaRequestTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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.format;
-
-import static com.seanyinx.github.unit.scaffolding.AssertUtils.expectFailing;
-import static com.seanyinx.github.unit.scaffolding.Randomness.uniquify;
-import static org.apache.servicecomb.saga.core.Operation.TYPE_REST;
-import static org.apache.servicecomb.saga.format.JacksonFallback.NOP_TRANSPORT_AWARE_FALLBACK;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.anyMap;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import org.apache.servicecomb.saga.transports.TransportFactory;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import org.apache.servicecomb.saga.transports.RestTransport;
-
-public class JsonRestSagaRequestTest {
-
-  private final RestTransport restTransport = Mockito.mock(RestTransport.class);
-  private final TransportFactory transportFactory = Mockito.mock(TransportFactory.class);
-  private final JacksonRestTransaction transaction = Mockito.mock(JacksonRestTransaction.class);
-  private final JacksonRestCompensation compensation = Mockito.mock(JacksonRestCompensation.class);
-
-  @Test
-  public void blowsUpIfTransactionIsNotSpecified() {
-    try {
-      newSagaRequest(null, compensation, NOP_TRANSPORT_AWARE_FALLBACK);
-
-      expectFailing(IllegalArgumentException.class);
-    } catch (IllegalArgumentException e) {
-      assertThat(e.getMessage(), is("Invalid request with NO transaction specified"));
-    }
-  }
-
-  @Test
-  public void blowsUpIfCompensationIsNotSpecified() {
-    try {
-      newSagaRequest(transaction, null, NOP_TRANSPORT_AWARE_FALLBACK);
-
-      expectFailing(IllegalArgumentException.class);
-    } catch (IllegalArgumentException e) {
-      assertThat(e.getMessage(), is("Invalid request with NO compensation specified"));
-    }
-  }
-
-  @SuppressWarnings("unchecked")
-  @Test
-  public void defaultToNopFallbackIfNotSpecified() {
-    when(transportFactory.restTransport()).thenReturn(restTransport);
-    JsonRestSagaRequest request = newSagaRequest(transaction, compensation, null);
-
-    request.with(transportFactory);
-
-    request.fallback().send(uniquify("blah"));
-
-    verify(restTransport, never()).with(anyString(), anyString(), anyString(), anyMap());
-  }
-
-  private JsonRestSagaRequest newSagaRequest(
-      JacksonRestTransaction transaction,
-      JacksonRestCompensation compensation,
-      JacksonFallback fallback) {
-
-    return new JsonRestSagaRequest(
-        uniquify("id"),
-        uniquify("serviceName"),
-        TYPE_REST,
-        transaction,
-        compensation,
-        fallback,
-        null,
-        0);
-  }
-}
diff --git a/saga-format/src/test/java/org/apache/servicecomb/saga/format/JsonSagaDefinitionTest.java b/saga-format/src/test/java/org/apache/servicecomb/saga/format/JsonSagaDefinitionTest.java
deleted file mode 100644
index 6228b662..00000000
--- a/saga-format/src/test/java/org/apache/servicecomb/saga/format/JsonSagaDefinitionTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.format;
-
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-
-import org.hamcrest.core.Is;
-import org.junit.Test;
-
-public class JsonSagaDefinitionTest {
-
-  @Test
-  public void backwardRecoveryIfNoPolicyProvided() {
-    JsonSagaDefinition definition = new JsonSagaDefinition(null, new JsonSagaRequest[0]);
-
-    assertThat(definition.policy(), Is.is(JsonSagaDefinition.backwardRecovery));
-  }
-}
diff --git a/saga-format/src/test/java/org/apache/servicecomb/saga/format/SagaEventFormatTest.java b/saga-format/src/test/java/org/apache/servicecomb/saga/format/SagaEventFormatTest.java
deleted file mode 100644
index 9bad69cb..00000000
--- a/saga-format/src/test/java/org/apache/servicecomb/saga/format/SagaEventFormatTest.java
+++ /dev/null
@@ -1,180 +0,0 @@
-
-/*
- * 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.format;
-
-import static org.apache.servicecomb.saga.core.Operation.TYPE_REST;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonMap;
-import static org.hamcrest.core.Is.is;
-import static org.hamcrest.core.IsInstanceOf.instanceOf;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import org.apache.servicecomb.saga.core.JacksonToJsonFormat;
-import org.apache.servicecomb.saga.core.SagaRequest;
-import org.apache.servicecomb.saga.core.SagaRequestImpl;
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.apache.servicecomb.saga.core.SuccessfulSagaResponse;
-import org.apache.servicecomb.saga.core.ToJsonFormat;
-import org.apache.servicecomb.saga.core.TransactionCompensatedEvent;
-import org.apache.servicecomb.saga.core.TransactionFailedException;
-import org.apache.servicecomb.saga.core.TransactionStartedEvent;
-import org.apache.servicecomb.saga.transports.TransportFactory;
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.hamcrest.TypeSafeMatcher;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.seanyinx.github.unit.scaffolding.Randomness;
-
-import org.apache.servicecomb.saga.core.FailedSagaResponse;
-import org.apache.servicecomb.saga.core.RestOperation;
-import org.apache.servicecomb.saga.core.SagaEvent;
-import org.apache.servicecomb.saga.core.TransactionAbortedEvent;
-import org.apache.servicecomb.saga.core.TransactionEndedEvent;
-import org.apache.servicecomb.saga.transports.RestTransport;
-
-public class SagaEventFormatTest {
-
-  private final String sagaId = Randomness.uniquify("sagaId");
-  private final SagaRequest request = new SagaRequestImpl(
-      sagaId,
-      Randomness.uniquify("serviceName"),
-      TYPE_REST,
-      new JacksonRestTransaction("/rest/xxx", "POST", singletonMap("query", singletonMap("foo", "xxx"))),
-      new JacksonRestCompensation("/rest/xxx", "DELETE", singletonMap("query", singletonMap("bar", "xxx"))),
-      new JacksonRestFallback(TYPE_REST, "/rest/xxx", "PUT", emptyMap())
-  );
-
-  private final RestTransport restTransport = Mockito.mock(RestTransport.class);
-  private final TransportFactory transportFactory = Mockito.mock(TransportFactory.class);
-  private final SagaEventFormat toEventFormat = new JacksonSagaEventFormat(transportFactory);
-  private final ToJsonFormat toJsonFormat = new JacksonToJsonFormat();
-  private final SuccessfulSagaResponse response = new SuccessfulSagaResponse("a wonderful day");
-
-  @Before
-  public void setUp() throws Exception {
-    when(transportFactory.restTransport()).thenReturn(restTransport);
-  }
-
-  @After
-  public void tearDown() throws Exception {
-    verify(transportFactory, times(3)).restTransport();
-  }
-
-  @Test
-  public void transactionStartedEventCanBeSerializedAndDeserialized() throws JsonProcessingException {
-    TransactionStartedEvent event = new TransactionStartedEvent(sagaId, request);
-    String json = event.json(toJsonFormat);
-
-    SagaEvent sagaEvent = toEventFormat
-        .toSagaEvent(sagaId, event.getClass().getSimpleName(), json);
-
-    assertThat(sagaEvent, instanceOf(TransactionStartedEvent.class));
-    assertThat(sagaEvent.sagaId, is(sagaId));
-    assertThat(sagaEvent.payload(), eqToRequest(request));
-  }
-
-  @Test
-  public void transactionEndedEventCanBeSerializedAndDeserialized() throws JsonProcessingException {
-    TransactionEndedEvent event = new TransactionEndedEvent(sagaId, request, response);
-    String json = event.json(toJsonFormat);
-
-    SagaEvent sagaEvent = toEventFormat
-        .toSagaEvent(sagaId, event.getClass().getSimpleName(), json);
-
-    assertThat(sagaEvent, instanceOf(TransactionEndedEvent.class));
-    assertThat(sagaEvent.sagaId, is(sagaId));
-    assertThat(sagaEvent.payload(), eqToRequest(request));
-    assertThat(((TransactionEndedEvent) sagaEvent).response(), eqToResponse(response));
-  }
-
-  @Test
-  public void TransactionAbortedEventCanBeSerializedAndDeserialized() throws JsonProcessingException {
-    TransactionFailedException exception = new TransactionFailedException("oops");
-    SagaEvent event = new TransactionAbortedEvent(sagaId, request, exception);
-    String json = event.json(toJsonFormat);
-
-    SagaEvent sagaEvent = toEventFormat
-        .toSagaEvent(sagaId, event.getClass().getSimpleName(), json);
-
-    assertThat(sagaEvent, instanceOf(TransactionAbortedEvent.class));
-    assertThat(sagaEvent.sagaId, is(sagaId));
-    assertThat(sagaEvent.payload(), eqToRequest(request));
-    assertThat(((TransactionAbortedEvent) sagaEvent).response(), eqToResponse(new FailedSagaResponse(exception)));
-  }
-
-  @Test
-  public void compensationEndedEventCanBeSerializedAndDeserialized() throws JsonProcessingException {
-    TransactionCompensatedEvent event = new TransactionCompensatedEvent(sagaId, request, response);
-    String json = event.json(toJsonFormat);
-
-    SagaEvent sagaEvent = toEventFormat
-        .toSagaEvent(sagaId, event.getClass().getSimpleName(), json);
-
-    assertThat(sagaEvent, instanceOf(TransactionCompensatedEvent.class));
-    assertThat(sagaEvent.sagaId, is(sagaId));
-    assertThat(sagaEvent.payload(), eqToRequest(request));
-    assertThat(((TransactionCompensatedEvent) sagaEvent).response(), eqToResponse(response));
-  }
-
-  private static Matcher<SagaRequest> eqToRequest(SagaRequest expected) {
-    return new TypeSafeMatcher<SagaRequest>() {
-      @Override
-      protected boolean matchesSafely(SagaRequest request) {
-        return expected.id().equals(request.id())
-            && request.serviceName().equals(expected.serviceName())
-            && request.task().equals(expected.task())
-            && request.type().equals(expected.type())
-            && ((RestOperation) request.transaction()).path().equals(((RestOperation) expected.transaction()).path())
-            && ((RestOperation) request.transaction()).method().equals(((RestOperation) expected.transaction()).method())
-            && ((RestOperation) request.compensation()).path().equals(((RestOperation) expected.compensation()).path())
-            && ((RestOperation) request.compensation()).method().equals(((RestOperation) expected.compensation()).method());
-      }
-
-      @Override
-      public void describeTo(Description description) {
-        description.appendText(expected.toString());
-      }
-    };
-
-  }
-
-  private static Matcher<SagaResponse> eqToResponse(SagaResponse expected) {
-    return new TypeSafeMatcher<SagaResponse>() {
-      @Override
-      protected boolean matchesSafely(SagaResponse response) {
-        return expected.body().equals(response.body())
-            && response.succeeded() == expected.succeeded();
-      }
-
-      @Override
-      public void describeTo(Description description) {
-        description.appendText(expected.toString());
-      }
-    };
-  }
-
-}
diff --git a/saga-performance/README.md b/saga-performance/README.md
deleted file mode 100644
index 7e4e55e4..00000000
--- a/saga-performance/README.md
+++ /dev/null
@@ -1,47 +0,0 @@
-# Saga Performance Test
-
-Performance test is automated with [JMeter](http://jmeter.apache.org/download_jmeter.cgi). A great tutorial can be found
-at [Guru99](https://www.guru99.com/jmeter-performance-testing.html) if you are not familiar with JMeter.
-
-## How to Run Performance Test
-To run performance test, execute the following JMeter command
-```
-jmeter -n -t saga.jmx -l log.jtl
-```
-
-To generate test report from JMeter test log, run the following JMeter command
-```
-jmeter -g log.jtl -o <report folder>
-```
-
-## How to Enable Kamon Metrics
-[Kamon](http://kamon.io/documentation/get-started/) is used to track saga performance and reports trace data to both log
-and [StatsD](https://github.com/etsy/statsd/). The easiest way to visualize tracing reports is to use a [docker image](http://kamon.io/documentation/kamon-statsd/0.6.6/overview/)
-composed with StatsD, [Graphite](http://graphite.wikidot.com/), and [Grafana](http://grafana.org/)
-
-1. Build saga with profile `perf`.
-```
-mvn package -Pperf
-```
-
-2. Run saga with aspectj and Kamon enabled. 
-By default, tracing data will be reported to StatsD running on `localhost` and port `8125`. To change the default StatsD
-host configuration, pass `-Dkamon.statsd.hostname=<hostname>` and `-Dkamon.statsd.port=<port>` as vm options when running
-saga.
-```
-java -javaagent:/path/to/aspectj-weaver.jar -Dkamon.modules.kamon-annotation.auto-start=yes -Dkamon.modules.kamon-log-reporter.auto-start=yes -Dkamon.modules.kamon-statsd.auto-start=yes -jar saga.jar
-```
-
-3. Add a new row with the following query in Grafana to display the segments of trace data. Please refer to [Grafana Tutorial](http://docs.grafana.org/guides/getting_started/)
-if you need some help
-
-![Grafana Metrics](images/grafana.png)
-
-## Recommended Test Setup
-Three test machines to run the following services on each:
-* saga
-* car service in saga-demo
-* MySQL
-
-The car service and saga can share the same machine, since car service consumes very little CPU and memory, and has no disk
-access.
diff --git a/saga-performance/images/grafana.png b/saga-performance/images/grafana.png
deleted file mode 100644
index 837b7778..00000000
Binary files a/saga-performance/images/grafana.png and /dev/null differ
diff --git a/saga-performance/scripts/saga.jmx b/saga-performance/scripts/saga.jmx
deleted file mode 100644
index 03f5cdcd..00000000
--- a/saga-performance/scripts/saga.jmx
+++ /dev/null
@@ -1,289 +0,0 @@
-<?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.
-  -->
-<jmeterTestPlan version="1.2" properties="3.2" jmeter="3.2 r1790748">
-  <hashTree>
-    <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
-      <stringProp name="TestPlan.comments"></stringProp>
-      <boolProp name="TestPlan.functional_mode">false</boolProp>
-      <boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
-      <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
-        <collectionProp name="Arguments.arguments"/>
-      </elementProp>
-      <stringProp name="TestPlan.user_define_classpath"></stringProp>
-    </TestPlan>
-    <hashTree>
-      <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
-        <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
-        <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
-          <boolProp name="LoopController.continue_forever">false</boolProp>
-          <intProp name="LoopController.loops">-1</intProp>
-        </elementProp>
-        <stringProp name="ThreadGroup.num_threads">200</stringProp>
-        <stringProp name="ThreadGroup.ramp_time">100</stringProp>
-        <longProp name="ThreadGroup.start_time">1503917597000</longProp>
-        <longProp name="ThreadGroup.end_time">1503917597000</longProp>
-        <boolProp name="ThreadGroup.scheduler">true</boolProp>
-        <stringProp name="ThreadGroup.duration">700</stringProp>
-        <stringProp name="ThreadGroup.delay"></stringProp>
-      </ThreadGroup>
-      <hashTree>
-        <ConfigTestElement guiclass="HttpDefaultsGui" testclass="ConfigTestElement" testname="HTTP Request Defaults" enabled="true">
-          <boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
-          <elementProp name="HTTPsampler.Arguments" elementType="Arguments">
-            <collectionProp name="Arguments.arguments">
-              <elementProp name="" elementType="HTTPArgument">
-                <boolProp name="HTTPArgument.always_encode">false</boolProp>
-                <stringProp name="Argument.value"></stringProp>
-                <stringProp name="Argument.metadata">=</stringProp>
-              </elementProp>
-            </collectionProp>
-          </elementProp>
-          <stringProp name="HTTPSampler.domain">localhost</stringProp>
-          <stringProp name="HTTPSampler.port">8080</stringProp>
-          <stringProp name="HTTPSampler.protocol"></stringProp>
-          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
-          <stringProp name="HTTPSampler.path"></stringProp>
-          <stringProp name="HTTPSampler.concurrentPool">6</stringProp>
-          <stringProp name="HTTPSampler.connect_timeout"></stringProp>
-          <stringProp name="HTTPSampler.response_timeout"></stringProp>
-        </ConfigTestElement>
-        <hashTree/>
-        <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
-          <collectionProp name="HeaderManager.headers">
-            <elementProp name="" elementType="Header">
-              <stringProp name="Header.name">Content-Type</stringProp>
-              <stringProp name="Header.value">application/json</stringProp>
-            </elementProp>
-          </collectionProp>
-        </HeaderManager>
-        <hashTree/>
-        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="HTTP Request" enabled="true">
-          <boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
-          <elementProp name="HTTPsampler.Arguments" elementType="Arguments">
-            <collectionProp name="Arguments.arguments">
-              <elementProp name="" elementType="HTTPArgument">
-                <boolProp name="HTTPArgument.always_encode">false</boolProp>
-                <stringProp name="Argument.value">[&#xd;
-  {&#xd;
-    &quot;id&quot;: &quot;request-car&quot;,&#xd;
-    &quot;type&quot;: &quot;rest&quot;,&#xd;
-    &quot;serviceName&quot;: &quot;localhost:9090&quot;,&#xd;
-    &quot;transaction&quot;: {&#xd;
-      &quot;method&quot;: &quot;post&quot;,&#xd;
-      &quot;path&quot;: &quot;/rentals&quot;,&#xd;
-      &quot;params&quot;: {&#xd;
-        &quot;json&quot;: {&#xd;
-          &quot;body&quot;: &quot;{ \&quot;customerId\&quot;: \&quot;mike\&quot; }&quot;&#xd;
-        }&#xd;
-      }&#xd;
-    },&#xd;
-    &quot;compensation&quot;: {&#xd;
-      &quot;method&quot;: &quot;put&quot;,&#xd;
-      &quot;path&quot;: &quot;/rentals&quot;,&#xd;
-      &quot;params&quot;: {&#xd;
-        &quot;json&quot;: {&#xd;
-          &quot;body&quot;: &quot;{ \&quot;customerId\&quot;: \&quot;mike\&quot; }&quot;&#xd;
-        }&#xd;
-      }&#xd;
-    }&#xd;
-  }&#xd;
-]</stringProp>
-                <stringProp name="Argument.metadata">=</stringProp>
-              </elementProp>
-            </collectionProp>
-          </elementProp>
-          <stringProp name="HTTPSampler.domain"></stringProp>
-          <stringProp name="HTTPSampler.port"></stringProp>
-          <stringProp name="HTTPSampler.protocol"></stringProp>
-          <stringProp name="HTTPSampler.contentEncoding"></stringProp>
-          <stringProp name="HTTPSampler.path">requests</stringProp>
-          <stringProp name="HTTPSampler.method">POST</stringProp>
-          <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
-          <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
-          <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
-          <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
-          <stringProp name="HTTPSampler.connect_timeout"></stringProp>
-          <stringProp name="HTTPSampler.response_timeout"></stringProp>
-        </HTTPSamplerProxy>
-        <hashTree/>
-        <ConstantTimer guiclass="ConstantTimerGui" testclass="ConstantTimer" testname="Constant Timer" enabled="true">
-          <stringProp name="ConstantTimer.delay">100</stringProp>
-        </ConstantTimer>
-        <hashTree/>
-        <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true">
-          <collectionProp name="Asserion.test_strings">
-            <stringProp name="49586">200</stringProp>
-          </collectionProp>
-          <stringProp name="Assertion.test_field">Assertion.response_code</stringProp>
-          <boolProp name="Assertion.assume_success">false</boolProp>
-          <intProp name="Assertion.test_type">2</intProp>
-        </ResponseAssertion>
-        <hashTree/>
-      </hashTree>
-      <ResultCollector guiclass="GraphVisualizer" testclass="ResultCollector" testname="Graph Results" enabled="true">
-        <boolProp name="ResultCollector.error_logging">false</boolProp>
-        <objProp>
-          <name>saveConfig</name>
-          <value class="SampleSaveConfiguration">
-            <time>true</time>
-            <latency>true</latency>
-            <timestamp>true</timestamp>
-            <success>true</success>
-            <label>true</label>
-            <code>true</code>
-            <message>true</message>
-            <threadName>true</threadName>
-            <dataType>true</dataType>
-            <encoding>false</encoding>
-            <assertions>true</assertions>
-            <subresults>true</subresults>
-            <responseData>false</responseData>
-            <samplerData>false</samplerData>
-            <xml>false</xml>
-            <fieldNames>true</fieldNames>
-            <responseHeaders>false</responseHeaders>
-            <requestHeaders>false</requestHeaders>
-            <responseDataOnError>false</responseDataOnError>
-            <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
-            <assertionsResultsToSave>0</assertionsResultsToSave>
-            <bytes>true</bytes>
-            <sentBytes>true</sentBytes>
-            <threadCounts>true</threadCounts>
-            <idleTime>true</idleTime>
-            <connectTime>true</connectTime>
-          </value>
-        </objProp>
-        <stringProp name="filename"></stringProp>
-      </ResultCollector>
-      <hashTree/>
-      <ResultCollector guiclass="TableVisualizer" testclass="ResultCollector" testname="View Results in Table" enabled="true">
-        <boolProp name="ResultCollector.error_logging">false</boolProp>
-        <objProp>
-          <name>saveConfig</name>
-          <value class="SampleSaveConfiguration">
-            <time>true</time>
-            <latency>true</latency>
-            <timestamp>true</timestamp>
-            <success>true</success>
-            <label>true</label>
-            <code>true</code>
-            <message>true</message>
-            <threadName>true</threadName>
-            <dataType>true</dataType>
-            <encoding>false</encoding>
-            <assertions>true</assertions>
-            <subresults>true</subresults>
-            <responseData>false</responseData>
-            <samplerData>false</samplerData>
-            <xml>false</xml>
-            <fieldNames>true</fieldNames>
-            <responseHeaders>false</responseHeaders>
-            <requestHeaders>false</requestHeaders>
-            <responseDataOnError>false</responseDataOnError>
-            <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
-            <assertionsResultsToSave>0</assertionsResultsToSave>
-            <bytes>true</bytes>
-            <sentBytes>true</sentBytes>
-            <threadCounts>true</threadCounts>
-            <idleTime>true</idleTime>
-            <connectTime>true</connectTime>
-          </value>
-        </objProp>
-        <stringProp name="filename"></stringProp>
-      </ResultCollector>
-      <hashTree/>
-      <ResultCollector guiclass="AssertionVisualizer" testclass="ResultCollector" testname="Assertion Results" enabled="true">
-        <boolProp name="ResultCollector.error_logging">false</boolProp>
-        <objProp>
-          <name>saveConfig</name>
-          <value class="SampleSaveConfiguration">
-            <time>true</time>
-            <latency>true</latency>
-            <timestamp>true</timestamp>
-            <success>true</success>
-            <label>true</label>
-            <code>true</code>
-            <message>true</message>
-            <threadName>true</threadName>
-            <dataType>true</dataType>
-            <encoding>false</encoding>
-            <assertions>true</assertions>
-            <subresults>true</subresults>
-            <responseData>false</responseData>
-            <samplerData>false</samplerData>
-            <xml>false</xml>
-            <fieldNames>true</fieldNames>
-            <responseHeaders>false</responseHeaders>
-            <requestHeaders>false</requestHeaders>
-            <responseDataOnError>false</responseDataOnError>
-            <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
-            <assertionsResultsToSave>0</assertionsResultsToSave>
-            <bytes>true</bytes>
-            <sentBytes>true</sentBytes>
-            <threadCounts>true</threadCounts>
-            <idleTime>true</idleTime>
-            <connectTime>true</connectTime>
-          </value>
-        </objProp>
-        <stringProp name="filename"></stringProp>
-      </ResultCollector>
-      <hashTree/>
-      <ResultCollector guiclass="StatVisualizer" testclass="ResultCollector" testname="Aggregate Report" enabled="true">
-        <boolProp name="ResultCollector.error_logging">false</boolProp>
-        <objProp>
-          <name>saveConfig</name>
-          <value class="SampleSaveConfiguration">
-            <time>true</time>
-            <latency>true</latency>
-            <timestamp>true</timestamp>
-            <success>true</success>
-            <label>true</label>
-            <code>true</code>
-            <message>true</message>
-            <threadName>true</threadName>
-            <dataType>true</dataType>
-            <encoding>false</encoding>
-            <assertions>true</assertions>
-            <subresults>true</subresults>
-            <responseData>false</responseData>
-            <samplerData>false</samplerData>
-            <xml>false</xml>
-            <fieldNames>true</fieldNames>
-            <responseHeaders>false</responseHeaders>
-            <requestHeaders>false</requestHeaders>
-            <responseDataOnError>false</responseDataOnError>
-            <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
-            <assertionsResultsToSave>0</assertionsResultsToSave>
-            <bytes>true</bytes>
-            <sentBytes>true</sentBytes>
-            <threadCounts>true</threadCounts>
-            <idleTime>true</idleTime>
-            <connectTime>true</connectTime>
-          </value>
-        </objProp>
-        <stringProp name="filename"></stringProp>
-      </ResultCollector>
-      <hashTree/>
-    </hashTree>
-    <WorkBench guiclass="WorkBenchGui" testclass="WorkBench" testname="WorkBench" enabled="true">
-      <boolProp name="WorkBench.save">true</boolProp>
-    </WorkBench>
-    <hashTree/>
-  </hashTree>
-</jmeterTestPlan>
diff --git a/saga-persistence/pom.xml b/saga-persistence/pom.xml
deleted file mode 100644
index 5f7bc20f..00000000
--- a/saga-persistence/pom.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?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</artifactId>
-    <groupId>org.apache.servicecomb.saga</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>saga-persistence</artifactId>
-  <packaging>pom</packaging>
-  <modules>
-    <module>saga-persistence-jpa</module>
-  </modules>
-
-
-</project>
diff --git a/saga-persistence/saga-persistence-jpa/pom.xml b/saga-persistence/saga-persistence-jpa/pom.xml
deleted file mode 100644
index 372b383e..00000000
--- a/saga-persistence/saga-persistence-jpa/pom.xml
+++ /dev/null
@@ -1,89 +0,0 @@
-<?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-persistence</artifactId>
-    <groupId>org.apache.servicecomb.saga</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>saga-persistence-jpa</artifactId>
-
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot-dependencies</artifactId>
-        <version>${spring.boot.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter-aop</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter-jdbc</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>javax.transaction</groupId>
-      <artifactId>javax.transaction-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.data</groupId>
-      <artifactId>spring-data-jpa</artifactId>
-      <exclusions>
-        <exclusion>
-          <groupId>org.aspectj</groupId>
-          <artifactId>aspectjrt</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-aspects</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.eclipse.persistence</groupId>
-      <artifactId>org.eclipse.persistence.jpa</artifactId>
-    </dependency>
-  </dependencies>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>com.ethlo.persistence.tools</groupId>
-        <artifactId>eclipselink-maven-plugin</artifactId>
-      </plugin>
-    </plugins>
-  </build>
-
-</project>
diff --git a/saga-persistence/saga-persistence-jpa/src/main/java/org/apache/servicecomb/saga/persistence/jpa/EclipseLinkJpaConfiguration.java b/saga-persistence/saga-persistence-jpa/src/main/java/org/apache/servicecomb/saga/persistence/jpa/EclipseLinkJpaConfiguration.java
deleted file mode 100644
index 1ad78798..00000000
--- a/saga-persistence/saga-persistence-jpa/src/main/java/org/apache/servicecomb/saga/persistence/jpa/EclipseLinkJpaConfiguration.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.persistence.jpa;
-
-import java.util.Collections;
-import java.util.Map;
-
-import javax.sql.DataSource;
-
-import org.springframework.beans.factory.ObjectProvider;
-import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration;
-import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
-import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
-import org.springframework.transaction.jta.JtaTransactionManager;
-
-@Configuration
-public class EclipseLinkJpaConfiguration extends JpaBaseConfiguration {
-  EclipseLinkJpaConfiguration(DataSource dataSource,
-      JpaProperties properties,
-      ObjectProvider<JtaTransactionManager> jtaTransactionManagerProvider) {
-    super(dataSource, properties, jtaTransactionManagerProvider);
-  }
-
-  @Override
-  protected AbstractJpaVendorAdapter createJpaVendorAdapter() {
-    return new EclipseLinkJpaVendorAdapter();
-  }
-
-  @Override
-  protected Map<String, Object> getVendorProperties() {
-    return Collections.singletonMap("eclipselink.weaving", "false");
-  }
-}
diff --git a/saga-persistence/saga-persistence-jpa/src/main/resources/META-INF/spring.factories b/saga-persistence/saga-persistence-jpa/src/main/resources/META-INF/spring.factories
deleted file mode 100644
index 1d6b8503..00000000
--- a/saga-persistence/saga-persistence-jpa/src/main/resources/META-INF/spring.factories
+++ /dev/null
@@ -1,18 +0,0 @@
-## ---------------------------------------------------------------------------
-## 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.
-## ---------------------------------------------------------------------------
-org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-  org.apache.servicecomb.saga.persistence.jpa.EclipseLinkJpaConfiguration
diff --git a/saga-spring/pom.xml b/saga-spring/pom.xml
deleted file mode 100755
index 38f51ccd..00000000
--- a/saga-spring/pom.xml
+++ /dev/null
@@ -1,233 +0,0 @@
-<?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</artifactId>
-    <groupId>org.apache.servicecomb.saga</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>saga-spring</artifactId>
-  <name>Saga::Spring</name>
-
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.apache.commons</groupId>
-        <artifactId>commons-lang3</artifactId>
-        <version>3.6</version>
-      </dependency>
-      <!-- java chassis jdbc version conflicts with the one defined in spring boot, so we override the version here -->
-      <dependency>
-        <groupId>org.springframework</groupId>
-        <artifactId>spring-jdbc</artifactId>
-        <version>${spring.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot-starter-test</artifactId>
-        <version>${spring.boot.version}</version>
-        <exclusions>
-          <exclusion>
-            <groupId>org.json</groupId>
-            <artifactId>json</artifactId>
-          </exclusion>
-        </exclusions>
-        <scope>test</scope>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb</groupId>
-        <artifactId>spring-boot-starter-provider</artifactId>
-        <version>${java.chassis.version}</version>
-        <exclusions>
-          <exclusion>
-            <groupId>com.google.code.findbugs</groupId>
-            <artifactId>annotations</artifactId>
-          </exclusion>
-        </exclusions>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb</groupId>
-        <artifactId>java-chassis-dependencies</artifactId>
-        <version>${java.chassis.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-      <dependency>
-        <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot-dependencies</artifactId>
-        <version>${spring.boot.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.servicecomb.saga</groupId>
-      <artifactId>saga-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.servicecomb.saga</groupId>
-      <artifactId>saga-format</artifactId>
-      <exclusions>
-        <exclusion>
-          <groupId>com.fasterxml.jackson.core</groupId>
-          <artifactId>*</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.servicecomb.saga.transports</groupId>
-      <artifactId>transport-httpclient-spring</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.servicecomb.saga.discovery</groupId>
-      <artifactId>saga-discovery-servicecenter</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter</artifactId>
-      <exclusions>
-        <exclusion>
-          <groupId>ch.qos.logback</groupId>
-          <artifactId>*</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter-web</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter-actuator</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>javax.persistence</groupId>
-      <artifactId>javax.persistence-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.servicecomb.saga</groupId>
-      <artifactId>saga-persistence-jpa</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.postgresql</groupId>
-      <artifactId>postgresql</artifactId>
-      <scope>runtime</scope>
-    </dependency>
-    <dependency>
-      <groupId>io.kamon</groupId>
-      <artifactId>kamon-core_2.12</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.kamon</groupId>
-      <artifactId>kamon-annotation_2.12</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.lmax</groupId>
-      <artifactId>disruptor</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>com.h2database</groupId>
-      <artifactId>h2</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter-test</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>com.github.tomakehurst</groupId>
-      <artifactId>wiremock-standalone</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.github.seanyinx</groupId>
-      <artifactId>unit-scaffolding</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.rest-assured</groupId>
-      <artifactId>rest-assured</artifactId>
-      <scope>test</scope>
-    </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>
-    <profile>
-      <id>perf</id>
-      <dependencies>
-        <dependency>
-          <groupId>io.kamon</groupId>
-          <artifactId>kamon-log-reporter_2.12</artifactId>
-        </dependency>
-        <dependency>
-          <groupId>io.kamon</groupId>
-          <artifactId>kamon-statsd_2.12</artifactId>
-        </dependency>
-        <dependency>
-          <groupId>io.kamon</groupId>
-          <artifactId>kamon-autoweave_2.12</artifactId>
-        </dependency>
-        <dependency>
-          <groupId>org.aspectj</groupId>
-          <artifactId>aspectjweaver</artifactId>
-        </dependency>
-      </dependencies>
-    </profile>
-  </profiles>
-
-</project>
diff --git a/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/JpaPersistentStore.java b/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/JpaPersistentStore.java
deleted file mode 100644
index 4c6e5f07..00000000
--- a/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/JpaPersistentStore.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.spring;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.servicecomb.saga.core.EventEnvelope;
-import org.apache.servicecomb.saga.core.ToJsonFormat;
-import org.apache.servicecomb.saga.format.SagaEventFormat;
-import org.apache.servicecomb.saga.core.PersistentStore;
-import org.apache.servicecomb.saga.core.SagaEvent;
-
-import kamon.annotation.EnableKamon;
-import kamon.annotation.Segment;
-
-@EnableKamon
-class JpaPersistentStore implements PersistentStore {
-
-  private final SagaEventRepo repo;
-  private final SagaEventFormat sagaEventFormat;
-  private final ToJsonFormat toJsonFormat;
-
-  JpaPersistentStore(SagaEventRepo repo, ToJsonFormat toJsonFormat, SagaEventFormat sagaEventFormat) {
-    this.repo = repo;
-    this.sagaEventFormat = sagaEventFormat;
-    this.toJsonFormat = toJsonFormat;
-  }
-
-  @Override
-  public Map<String, List<EventEnvelope>> findPendingSagaEvents() {
-    List<SagaEventEntity> events = repo.findIncompleteSagaEventsGroupBySagaId();
-
-    Map<String, List<EventEnvelope>> pendingEvents = new HashMap<>();
-    for (SagaEventEntity event : events) {
-      pendingEvents.computeIfAbsent(event.sagaId(), id -> new LinkedList<>());
-      pendingEvents.get(event.sagaId()).add(
-          new EventEnvelope(
-              event.id(),
-              event.creationTime(),
-              sagaEventFormat.toSagaEvent(event.sagaId(), event.type(), event.contentJson())));
-    }
-
-    return pendingEvents;
-  }
-
-  @Segment(name = "save", category = "database", library = "kamon")
-  @Override
-  public void offer(SagaEvent event) {
-    repo.save(new SagaEventEntity(event.sagaId, event.getClass().getSimpleName(), event.json(toJsonFormat)));
-  }
-}
diff --git a/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaController.java b/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaController.java
deleted file mode 100644
index 1a73b7bf..00000000
--- a/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaController.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * 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.spring;
-
-import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY;
-import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE;
-import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
-import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
-import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE;
-import static org.springframework.web.bind.annotation.RequestMethod.GET;
-import static org.springframework.web.bind.annotation.RequestMethod.POST;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.CrossOrigin;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-
-import com.fasterxml.jackson.annotation.JsonAutoDetect;
-
-import io.servicecomb.provider.rest.common.RestSchema;
-import org.apache.servicecomb.saga.core.SagaException;
-import org.apache.servicecomb.saga.core.application.SagaExecutionComponent;
-import io.servicecomb.swagger.invocation.exception.InvocationException;
-import io.swagger.annotations.ApiResponse;
-import io.swagger.annotations.ApiResponses;
-import kamon.annotation.EnableKamon;
-import kamon.annotation.Trace;
-
-@EnableKamon
-@Controller
-@RequestMapping("/")
-@RestSchema(schemaId = "saga-endpoint")
-public class SagaController {
-
-  private final SagaExecutionComponent sagaExecutionComponent;
-  private final SagaEventRepo repo;
-  private final SagaExecutionQueryService queryService;
-  private final SimpleDateFormat dateFormat;
-
-  @Autowired
-  public SagaController(SagaExecutionComponent sagaExecutionComponent, SagaEventRepo repo,
-      SagaExecutionQueryService queryService) {
-    this.sagaExecutionComponent = sagaExecutionComponent;
-    this.repo = repo;
-    this.queryService = queryService;
-    this.dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-  }
-
-  @Trace("processRequests")
-  @ApiResponses({
-      @ApiResponse(code = 200, response = String.class, message = "success"),
-      @ApiResponse(code = 400, response = String.class, message = "illegal request content"),
-      @ApiResponse(code = 500, response = String.class, message = "transaction failed")
-  })
-  @CrossOrigin
-  @RequestMapping(value = "requests", method = POST, consumes = TEXT_PLAIN_VALUE, produces = TEXT_PLAIN_VALUE)
-  public ResponseEntity<String> processRequests(@RequestBody String request) {
-    try {
-      SagaResponse response = sagaExecutionComponent.run(request);
-      if (response.succeeded()) {
-        return ResponseEntity.ok("success");
-      } else {
-        throw new InvocationException(INTERNAL_SERVER_ERROR, response.body());
-      }
-    } catch (SagaException se) {
-      throw new InvocationException(BAD_REQUEST, se);
-    }
-  }
-
-  @RequestMapping(value = "events", method = GET)
-  public ResponseEntity<Map<String, List<SagaEventVo>>> allEvents() {
-    Iterable<SagaEventEntity> entities = repo.findAll();
-
-    Map<String, List<SagaEventVo>> events = new LinkedHashMap<>();
-    entities.forEach(e -> {
-      events.computeIfAbsent(e.sagaId(), id -> new LinkedList<>());
-      events.get(e.sagaId()).add(new SagaEventVo(e.id(), e.sagaId(), e.creationTime(), e.type(), e.contentJson()));
-    });
-
-    return ResponseEntity.ok(events);
-  }
-
-  @ApiResponses({
-      @ApiResponse(code = 200, response = String.class, message = "success"),
-      @ApiResponse(code = 400, response = String.class, message = "illegal request content"),
-  })
-  @CrossOrigin
-  @RequestMapping(value = "requests", method = GET)
-  public ResponseEntity<SagaExecutionQueryResult> queryExecutions(
-      @RequestParam(name = "pageIndex") String pageIndex,
-      @RequestParam(name = "pageSize") String pageSize,
-      @RequestParam(name = "startTime") String startTime,
-      @RequestParam(name = "endTime") String endTime) {
-    if (isRequestParamValid(pageIndex, pageSize, startTime, endTime)) {
-      try {
-        return ResponseEntity.ok(queryService.querySagaExecution(pageIndex, pageSize, startTime, endTime));
-      } catch (ParseException ignored) {
-        throw new InvocationException(BAD_REQUEST, "illegal request content");
-      }
-    } else {
-      throw new InvocationException(BAD_REQUEST, "illegal request content");
-    }
-  }
-
-  private boolean isRequestParamValid(String pageIndex, String pageSize, String startTime, String endTime) {
-    try {
-      if (Integer.parseInt(pageIndex) >= 0 && Integer.parseInt(pageSize) > 0) {
-        Date start = "NaN-NaN-NaN NaN:NaN:NaN".equals(startTime) ? new Date(0) : this.dateFormat.parse(startTime);
-        Date end =
-            "NaN-NaN-NaN NaN:NaN:NaN".equals(endTime) ? new Date(Long.MAX_VALUE) : this.dateFormat.parse(endTime);
-        return start.getTime() <= end.getTime();
-      }
-    } catch (NumberFormatException | ParseException ignored) {
-    }
-    return false;
-  }
-
-  @ApiResponses({
-      @ApiResponse(code = 200, response = String.class, message = "success"),
-  })
-  @CrossOrigin
-  @RequestMapping(value = "requests/{sagaId}", method = GET)
-  public ResponseEntity<SagaExecutionDetail> queryExecutionDetail(@PathVariable String sagaId) {
-    return ResponseEntity.ok(queryService.querySagaExecutionDetail(sagaId));
-  }
-
-  @JsonAutoDetect(fieldVisibility = ANY, getterVisibility = NONE, setterVisibility = NONE)
-  private static class SagaEventVo extends SagaEventEntity {
-
-    private SagaEventVo(long id, String sagaId, long creationTime, String type, String contentJson) {
-      super(id, sagaId, creationTime, type, contentJson);
-    }
-  }
-
-  @JsonAutoDetect(fieldVisibility = ANY, getterVisibility = NONE, setterVisibility = NONE)
-  static class SagaExecutionQueryResult {
-    public int pageIndex;
-    public int pageSize;
-    public int totalPages;
-
-    public List<SagaExecution> requests;
-
-    public SagaExecutionQueryResult() {
-    }
-
-    public SagaExecutionQueryResult(int pageIndex, int pageSize, int totalPages, List<SagaExecution> requests) {
-      this();
-      this.pageIndex = pageIndex;
-      this.pageSize = pageSize;
-      this.totalPages = totalPages;
-      this.requests = requests;
-    }
-  }
-
-  @JsonAutoDetect(fieldVisibility = ANY, getterVisibility = NONE, setterVisibility = NONE)
-  static class SagaExecution {
-    public long id;
-    public String sagaId;
-    public long startTime;
-    public String status;
-    public long completedTime;
-
-    public SagaExecution() {
-    }
-
-    public SagaExecution(long id, String sagaId, long startTime, long completedTime, String status) {
-      this();
-      this.id = id;
-      this.sagaId = sagaId;
-      this.startTime = startTime;
-      this.completedTime = completedTime;
-      this.status = status;
-    }
-  }
-
-  @JsonAutoDetect(fieldVisibility = ANY, getterVisibility = NONE, setterVisibility = NONE)
-  static class SagaExecutionDetail {
-    public Map<String, HashSet<String>> router;
-    public Map<String, String> status;
-    public Map<String, String> error;
-
-    public SagaExecutionDetail() {
-    }
-
-    public SagaExecutionDetail(Map<String, HashSet<String>> router, Map<String, String> status,
-        Map<String, String> error) {
-      this();
-      this.router = router;
-      this.status = status;
-      this.error = error;
-    }
-  }
-}
diff --git a/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaEventEntity.java b/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaEventEntity.java
deleted file mode 100644
index 6be35013..00000000
--- a/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaEventEntity.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.spring;
-
-import java.util.Date;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-
-@Entity
-public class SagaEventEntity {
-  @Id
-  @GeneratedValue(strategy = GenerationType.IDENTITY)
-  private Long id;
-  private String sagaId;
-  private Date creationTime;
-  private String type;
-  private String contentJson;
-
-  public SagaEventEntity() {
-  }
-
-  public SagaEventEntity(String sagaId, String type, String contentJson) {
-    this.sagaId = sagaId;
-    this.type = type;
-    this.contentJson = contentJson;
-    this.creationTime = new Date();
-  }
-
-  public SagaEventEntity(long id, String sagaId, long timestamp, String type, String contentJson) {
-    this.id = id;
-    this.sagaId = sagaId;
-    this.creationTime = new Date(timestamp);
-    this.type = type;
-    this.contentJson = contentJson;
-  }
-
-  public long id() {
-    return id;
-  }
-
-  public String sagaId() {
-    return sagaId;
-  }
-
-  public long creationTime() {
-    return creationTime.getTime();
-  }
-
-  public String type() {
-    return type;
-  }
-
-  public String contentJson() {
-    return contentJson;
-  }
-
-  @Override
-  public String toString() {
-    return "SagaEventEntity{" +
-        "id=" + id +
-        ", sagaId='" + sagaId + '\'' +
-        ", creationTime=" + creationTime +
-        ", type='" + type + '\'' +
-        ", contentJson='" + contentJson + '\'' +
-        '}';
-  }
-}
diff --git a/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaEventRepo.java b/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaEventRepo.java
deleted file mode 100644
index 1f1132b3..00000000
--- a/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaEventRepo.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.spring;
-
-import java.util.Date;
-import java.util.List;
-
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.PagingAndSortingRepository;
-
-interface SagaEventRepo extends PagingAndSortingRepository<SagaEventEntity, Long> {
-
-  // TODO: 8/21/2017 replace with hql?
-  @Query(value = "SELECT * FROM SagaEventEntity "
-      + "WHERE sagaId NOT IN ("
-      + "  SELECT DISTINCT sagaId FROM SagaEventEntity"
-      + "  WHERE type = 'SagaEndedEvent'"
-      + ")", nativeQuery = true)
-  List<SagaEventEntity> findIncompleteSagaEventsGroupBySagaId();
-
-  Page<SagaEventEntity> findByTypeAndCreationTimeBetweenOrderByIdDesc(String type, Date startTime, Date endTime,
-      Pageable pageable);
-
-  SagaEventEntity findFirstByTypeAndSagaId(String type, String sagaId);
-
-  List<SagaEventEntity> findBySagaId(String sagaId);
-}
diff --git a/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaExecutionQueryService.java b/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaExecutionQueryService.java
deleted file mode 100644
index 15f8cc59..00000000
--- a/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaExecutionQueryService.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * 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.spring;
-
-import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
-
-import java.io.IOException;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.stream.Collectors;
-
-import org.apache.servicecomb.saga.core.SagaRequest;
-import org.apache.servicecomb.saga.core.SagaStartedEvent;
-import org.apache.servicecomb.saga.core.dag.GraphCycleDetectorImpl;
-import org.apache.servicecomb.saga.core.dag.Node;
-import org.apache.servicecomb.saga.core.dag.SingleLeafDirectedAcyclicGraph;
-import org.apache.servicecomb.saga.spring.SagaController.SagaExecution;
-import org.apache.servicecomb.saga.spring.SagaController.SagaExecutionDetail;
-import org.apache.servicecomb.saga.spring.SagaController.SagaExecutionQueryResult;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.stereotype.Service;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import org.apache.servicecomb.saga.core.SagaDefinition;
-import org.apache.servicecomb.saga.core.SagaEndedEvent;
-import org.apache.servicecomb.saga.core.TransactionAbortedEvent;
-import org.apache.servicecomb.saga.core.TransactionEndedEvent;
-import org.apache.servicecomb.saga.core.application.interpreter.FromJsonFormat;
-import org.apache.servicecomb.saga.core.dag.GraphBuilder;
-
-import io.servicecomb.swagger.invocation.exception.InvocationException;
-
-@Service
-public class SagaExecutionQueryService {
-  private final SagaEventRepo repo;
-  private final FromJsonFormat<SagaDefinition> fromJsonFormat;
-  private final SimpleDateFormat dateFormat;
-
-  private final ObjectMapper mapper = new ObjectMapper();
-  private final GraphBuilder graphBuilder = new GraphBuilder(new GraphCycleDetectorImpl<>());
-
-  @Autowired
-  public SagaExecutionQueryService(SagaEventRepo repo, FromJsonFormat<SagaDefinition> fromJsonFormat) {
-    this.repo = repo;
-    this.fromJsonFormat = fromJsonFormat;
-    this.dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-  }
-
-  public SagaExecutionQueryResult querySagaExecution(String pageIndex, String pageSize,
-      String startTime, String endTime) throws ParseException {
-
-    Date start = "NaN-NaN-NaN NaN:NaN:NaN".equals(startTime) ? new Date(0) : this.dateFormat.parse(startTime);
-    Date end = "NaN-NaN-NaN NaN:NaN:NaN".equals(endTime) ? new Date() : this.dateFormat.parse(endTime);
-
-    List<SagaExecution> requests = new ArrayList<>();
-    Page<SagaEventEntity> startEvents = repo.findByTypeAndCreationTimeBetweenOrderByIdDesc(
-        SagaStartedEvent.class.getSimpleName(), start, end,
-        new PageRequest(Integer.parseInt(pageIndex), Integer.parseInt(pageSize)));
-    for (SagaEventEntity event : startEvents) {
-      SagaEventEntity endEvent = repo
-          .findFirstByTypeAndSagaId(SagaEndedEvent.class.getSimpleName(), event.sagaId());
-      SagaEventEntity abortedEvent = repo
-          .findFirstByTypeAndSagaId(TransactionAbortedEvent.class.getSimpleName(), event.sagaId());
-
-      requests.add(new SagaExecution(
-          event.id(),
-          event.sagaId(),
-          event.creationTime(),
-          endEvent == null ? 0 : endEvent.creationTime(),
-          endEvent == null ? "Running" : abortedEvent == null ? "OK" : "Failed"));
-    }
-
-    return new SagaExecutionQueryResult(Integer.parseInt(pageIndex), Integer.parseInt(pageSize),
-        startEvents.getTotalPages(), requests);
-  }
-
-  public SagaExecutionDetail querySagaExecutionDetail(String sagaId) {
-    SagaEventEntity[] entities = repo.findBySagaId(sagaId).toArray(new SagaEventEntity[0]);
-    Optional<SagaEventEntity> sagaStartEvent = Arrays.stream(entities)
-        .filter(entity -> SagaStartedEvent.class.getSimpleName().equals(entity.type())).findFirst();
-    Map<String, HashSet<String>> router = new HashMap<>();
-    Map<String, String> status = new HashMap<>();
-    Map<String, String> error = new HashMap<>();
-    if (sagaStartEvent.isPresent()) {
-      SagaDefinition definition = fromJsonFormat.fromJson(sagaStartEvent.get().contentJson());
-      SingleLeafDirectedAcyclicGraph<SagaRequest> graph = graphBuilder
-          .build(definition.requests());
-      loopLoadGraphNodes(router, graph.root());
-
-      Collection<SagaEventEntity> transactionAbortEvents = Arrays.stream(entities)
-          .filter(entity -> TransactionAbortedEvent.class.getSimpleName().equals(entity.type())).collect(
-              Collectors.toList());
-      for (SagaEventEntity transactionAbortEvent : transactionAbortEvents) {
-        try {
-          JsonNode root = mapper.readTree(transactionAbortEvent.contentJson());
-          String id = root.at("/request/id").asText();
-          status.put(id, "Failed");
-          error.put(id, root.at("/response/body").asText());
-        } catch (IOException ex) {
-          throw new InvocationException(INTERNAL_SERVER_ERROR, "illegal json content");
-        }
-      }
-
-      Collection<SagaEventEntity> transactionEndEvents = Arrays.stream(entities)
-          .filter(entity -> TransactionEndedEvent.class.getSimpleName().equals(entity.type())).collect(
-              Collectors.toList());
-      for (SagaEventEntity transactionEndEvent : transactionEndEvents) {
-        try {
-          JsonNode root = mapper.readTree(transactionEndEvent.contentJson());
-          status.put(root.at("/request/id").asText(), "OK");
-        } catch (IOException ex) {
-          throw new InvocationException(INTERNAL_SERVER_ERROR, "illegal json content");
-        }
-      }
-    }
-    return new SagaExecutionDetail(router, status, error);
-  }
-
-  private void loopLoadGraphNodes(Map<String, HashSet<String>> router, Node<SagaRequest> node) {
-    if (isNodeValid(node)) {
-      HashSet<String> point = router.computeIfAbsent(node.value().id(), key -> new HashSet<>());
-      for (Node<SagaRequest> child : node.children()) {
-        point.add(child.value().id());
-        loopLoadGraphNodes(router, child);
-      }
-    }
-  }
-
-  private boolean isNodeValid(Node<SagaRequest> node) {
-    return !node.children().isEmpty();
-  }
-}
diff --git a/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaRecoveryListener.java b/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaRecoveryListener.java
deleted file mode 100644
index 6b6e31d3..00000000
--- a/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaRecoveryListener.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.spring;
-
-import java.lang.invoke.MethodHandles;
-
-import org.apache.servicecomb.saga.core.application.SagaExecutionComponent;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.boot.context.event.ApplicationReadyEvent;
-import org.springframework.context.ApplicationListener;
-
-class SagaRecoveryListener implements ApplicationListener<ApplicationReadyEvent> {
-  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-  @Override
-  public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
-    log.info("Recovering pending sagas from saga log");
-    applicationReadyEvent.getApplicationContext().getBean(SagaExecutionComponent.class).reanimate();
-    log.info("Recovered pending sagas from saga log successfully");
-  }
-}
diff --git a/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaShutdownListener.java b/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaShutdownListener.java
deleted file mode 100644
index 8ec862ec..00000000
--- a/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaShutdownListener.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.spring;
-
-
-import org.apache.servicecomb.saga.core.application.SagaExecutionComponent;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.ApplicationListener;
-import org.springframework.context.event.ContextClosedEvent;
-
-import java.lang.invoke.MethodHandles;
-
-public class SagaShutdownListener implements ApplicationListener<ContextClosedEvent> {
-    private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-    @Override
-    public void onApplicationEvent(ContextClosedEvent contextClosedEvent) {
-        try {
-            log.info("Stopping sagas");
-            contextClosedEvent.getApplicationContext().getBean(SagaExecutionComponent.class).terminate();
-            log.info("Stopped sagas successfully.");
-        } catch (Exception ex) {
-            log.error("Stopped sagas failed.", ex);
-        }
-    }
-}
diff --git a/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaSpringApplication.java b/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaSpringApplication.java
deleted file mode 100644
index 3e17c14b..00000000
--- a/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaSpringApplication.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.spring;
-
-import javax.annotation.PreDestroy;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-import kamon.Kamon;
-
-@SpringBootApplication
-public class SagaSpringApplication {
-
-  public static void main(String[] args) {
-    Kamon.start();
-    SpringApplication.run(SagaSpringApplication.class, args);
-  }
-
-  @PreDestroy
-  void shutdown() {
-    Kamon.shutdown();
-  }
-}
diff --git a/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaSpringConfig.java b/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaSpringConfig.java
deleted file mode 100644
index d40f724f..00000000
--- a/saga-spring/src/main/java/org/apache/servicecomb/saga/spring/SagaSpringConfig.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * 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.spring;
-
-import java.util.Set;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.servicecomb.saga.core.JacksonToJsonFormat;
-import org.apache.servicecomb.saga.core.ToJsonFormat;
-import org.apache.servicecomb.saga.core.actors.ActorBasedSagaFactory;
-import org.apache.servicecomb.saga.core.application.SagaExecutionComponent;
-import org.apache.servicecomb.saga.core.application.SagaFactory;
-import org.apache.servicecomb.saga.core.dag.GraphBasedSagaFactory;
-import org.apache.servicecomb.saga.format.ChildrenExtractor;
-import org.apache.servicecomb.saga.format.JacksonFromJsonFormat;
-import org.apache.servicecomb.saga.format.SagaEventFormat;
-import org.apache.servicecomb.saga.transports.TransportFactory;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import org.apache.servicecomb.saga.core.PersistentStore;
-import org.apache.servicecomb.saga.core.SagaDefinition;
-import org.apache.servicecomb.saga.core.application.interpreter.FromJsonFormat;
-import org.apache.servicecomb.saga.format.JacksonSagaEventFormat;
-import org.apache.servicecomb.saga.transports.RestTransport;
-
-@Configuration
-class SagaSpringConfig {
-
-  @Bean
-  TransportFactory transportFactory(RestTransport restTransport) {
-    return () -> restTransport;
-  }
-
-  @Bean
-  FromJsonFormat<SagaDefinition> fromJsonFormat(TransportFactory transportFactory) {
-    return new JacksonFromJsonFormat(transportFactory);
-  }
-
-  @Bean
-  ToJsonFormat toJsonFormat() {
-    return new JacksonToJsonFormat();
-  }
-
-  @Bean
-  SagaEventFormat sagaEventFormat(TransportFactory transportFactory) {
-    return new JacksonSagaEventFormat(transportFactory);
-  }
-
-  @Bean
-  PersistentStore persistentStore(SagaEventRepo repo, ToJsonFormat toJsonFormat, SagaEventFormat eventFormat) {
-    return new JpaPersistentStore(repo, toJsonFormat, eventFormat);
-  }
-
-  @Bean
-  SagaExecutionQueryService queryService(SagaEventRepo repo, FromJsonFormat<SagaDefinition> fromJsonFormat) {
-    return new SagaExecutionQueryService(repo, fromJsonFormat);
-  }
-
-  @Bean
-  SagaExecutionComponent sagaExecutionComponent(
-      PersistentStore persistentStore,
-      ToJsonFormat format,
-      FromJsonFormat<SagaDefinition> fromJsonFormat,
-      SagaFactory sagaFactory) {
-
-    return new SagaExecutionComponent(
-        persistentStore,
-        fromJsonFormat,
-        format,
-        sagaFactory);
-  }
-
-  @Bean
-  FromJsonFormat<Set<String>> childrenExtractor() {
-    return new ChildrenExtractor();
-  }
-
-  @ConditionalOnProperty(value = "saga.runningMode", havingValue = "graph", matchIfMissing = true)
-  @Bean
-  SagaFactory graphBasedSagaFactory(
-      @Value("${saga.thread.count:5}") int numberOfThreads,
-      @Value("${saga.retry.delay:3000}") int retryDelay,
-      PersistentStore persistentStore,
-      FromJsonFormat<Set<String>> childrenExtractor) {
-
-    return new GraphBasedSagaFactory(
-        retryDelay,
-        persistentStore,
-        childrenExtractor,
-        Executors.newFixedThreadPool(numberOfThreads, sagaThreadFactory()));
-  }
-
-  @ConditionalOnProperty(value = "saga.runningMode", havingValue = "actor")
-  @Bean
-  SagaFactory actorBasedSagaFactory(
-      @Value("${saga.retry.delay:3000}") int retryDelay,
-      PersistentStore persistentStore,
-      FromJsonFormat<Set<String>> childrenExtractor) {
-
-    return new ActorBasedSagaFactory(
-        retryDelay,
-        persistentStore,
-        childrenExtractor);
-  }
-
-  private ThreadFactory sagaThreadFactory() {
-    return new ThreadFactory() {
-      private final AtomicInteger threadCount = new AtomicInteger();
-
-      @Override
-      public Thread newThread(Runnable r) {
-        return new Thread(r, "saga-pool-thread-" + threadCount.incrementAndGet());
-      }
-    };
-  }
-}
diff --git a/saga-spring/src/main/resources/META-INF/aop.xml b/saga-spring/src/main/resources/META-INF/aop.xml
deleted file mode 100644
index c4810363..00000000
--- a/saga-spring/src/main/resources/META-INF/aop.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-  ~ 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 aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
-
-<aspectj>
-  <weaver options="-Xlint:ignore">
-    <include within="org.apache.servicecomb.saga..*"/>
-    <exclude within="org.aspectj.*"/>
-  </weaver>
-</aspectj>
diff --git a/saga-spring/src/main/resources/META-INF/spring.factories b/saga-spring/src/main/resources/META-INF/spring.factories
deleted file mode 100644
index ff5b14fd..00000000
--- a/saga-spring/src/main/resources/META-INF/spring.factories
+++ /dev/null
@@ -1,20 +0,0 @@
-## ---------------------------------------------------------------------------
-## 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.
-## ---------------------------------------------------------------------------
-
-org.springframework.context.ApplicationListener=\
-  org.apache.servicecomb.saga.spring.SagaRecoveryListener,\
-  org.apache.servicecomb.saga.spring.SagaShutdownListener
diff --git a/saga-spring/src/main/resources/application.conf b/saga-spring/src/main/resources/application.conf
deleted file mode 100644
index d50e5916..00000000
--- a/saga-spring/src/main/resources/application.conf
+++ /dev/null
@@ -1,88 +0,0 @@
-## ---------------------------------------------------------------------------
-## 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.
-## ---------------------------------------------------------------------------
-
-###############################
-# Kamon related configuration #
-###############################
-
-kamon {
-
-  metric {
-    filters {
-      trace.includes = ["**"]
-      trace-segment.includes = ["**"]
-      trace-segment.excludes = []
-      akka-actor.includes = []
-      akka-actor.excludes = ["**"]
-      akka-dispatcher.includes = []
-      akka-dispatcher.excludes = ["**"]
-    }
-  }
-
-  show-aspectj-missing-warning = no
-
-  modules {
-    kamon-annotation {
-      auto-start = no
-      requires-aspectj = yes
-    }
-
-    kamon-log-reporter {
-      auto-start = no
-      requires-aspectj = no
-    }
-
-    kamon-statsd {
-      auto-start = no
-      requires-aspectj = no
-    }
-  }
-
-  statsd {
-    # Hostname and port in which your StatsD is running. Remember that StatsD packets are sent using UDP and
-    # setting unreachable hosts and/or not open ports wont be warned by the Kamon, your data wont go anywhere.
-    hostname = "localhost"
-    port = 8125
-
-    # Interval between metrics data flushes to StatsD. It's value must be equal or greater than the
-    # kamon.metrics.tick-interval setting.
-    flush-interval = 10 second
-
-    # Subscription patterns used to select which metrics will be pushed to StatsD. Note that first, metrics
-    # collection for your desired entities must be activated under the kamon.metrics.filters settings.
-    includes {
-      actor = []
-      trace = ["*"]
-      trace-segment = ["*"]
-      dispatcher = []
-    }
-
-    subscriptions {
-      histogram = ["**"]
-      min-max-counter = ["**"]
-      gauge = ["**"]
-      counter = ["**"]
-      trace = ["**"]
-      trace-segment = ["**"]
-      akka-actor = []
-      akka-dispatcher = []
-      akka-router = []
-      system-metric = []
-      http-server = []
-    }
-  }
-}
diff --git a/saga-spring/src/main/resources/application.yaml b/saga-spring/src/main/resources/application.yaml
deleted file mode 100644
index 6ed0d9d5..00000000
--- a/saga-spring/src/main/resources/application.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-## ---------------------------------------------------------------------------
-## 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:
-  profiles: prd
-  datasource:
-    username: saga
-    password: password
-    url: jdbc:postgresql://postgres.servicecomb.io:5432/saga?useSSL=false
-    platform: postgresql
-#    continue-on-error: true
-
-saga:
-  thread:
-    count: 32
-  retry:
-    delay: 3000
diff --git a/saga-spring/src/main/resources/log4j2.xml b/saga-spring/src/main/resources/log4j2.xml
deleted file mode 100644
index cae04cb9..00000000
--- a/saga-spring/src/main/resources/log4j2.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?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-spring/src/main/resources/schema-postgresql.sql b/saga-spring/src/main/resources/schema-postgresql.sql
deleted file mode 100644
index 7a2cd1fe..00000000
--- a/saga-spring/src/main/resources/schema-postgresql.sql
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.
- */
-
-CREATE TABLE IF NOT EXISTS SagaEventEntity (
-  id BIGSERIAL PRIMARY KEY,
-  sagaId varchar(36) NOT NULL,
-  creationTime timestamp(6) NOT NULL DEFAULT CURRENT_DATE,
-  type varchar(50) NOT NULL,
-  contentJson TEXT NOT NULL
-);
-
-CREATE INDEX IF NOT EXISTS running_sagas_index ON SagaEventEntity (sagaId, type);
diff --git a/saga-spring/src/test/java/org/apache/servicecomb/saga/spring/ActorBasedSagaSpringApplicationTest.java b/saga-spring/src/test/java/org/apache/servicecomb/saga/spring/ActorBasedSagaSpringApplicationTest.java
deleted file mode 100644
index f8826723..00000000
--- a/saga-spring/src/test/java/org/apache/servicecomb/saga/spring/ActorBasedSagaSpringApplicationTest.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.spring;
-
-import org.springframework.boot.test.context.SpringBootTest;
-
-@SpringBootTest(classes = SagaSpringApplication.class, properties = "saga.runningMode=actor")
-public class ActorBasedSagaSpringApplicationTest extends SagaSpringApplicationTestBase {
-
-}
diff --git a/saga-spring/src/test/java/org/apache/servicecomb/saga/spring/GraphBasedSagaSpringApplicationTest.java b/saga-spring/src/test/java/org/apache/servicecomb/saga/spring/GraphBasedSagaSpringApplicationTest.java
deleted file mode 100644
index f5fddcb8..00000000
--- a/saga-spring/src/test/java/org/apache/servicecomb/saga/spring/GraphBasedSagaSpringApplicationTest.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.spring;
-
-import org.springframework.boot.test.context.SpringBootTest;
-
-@SpringBootTest(classes = SagaSpringApplication.class)
-public class GraphBasedSagaSpringApplicationTest extends SagaSpringApplicationTestBase {
-
-}
diff --git a/saga-spring/src/test/java/org/apache/servicecomb/saga/spring/GreetingController.java b/saga-spring/src/test/java/org/apache/servicecomb/saga/spring/GreetingController.java
deleted file mode 100644
index 0710c018..00000000
--- a/saga-spring/src/test/java/org/apache/servicecomb/saga/spring/GreetingController.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.spring;
-
-import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE;
-import static org.springframework.web.bind.annotation.RequestMethod.POST;
-
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestAttribute;
-import org.springframework.web.bind.annotation.RequestMapping;
-
-import io.servicecomb.provider.rest.common.RestSchema;
-
-@Controller
-@RequestMapping("/rest")
-@RestSchema(schemaId = "greeting-rest-endpoint")
-public class GreetingController {
-
-  @RequestMapping(value = "/usableResource", method = POST, consumes = APPLICATION_FORM_URLENCODED_VALUE)
-  public ResponseEntity<String> postUsableResource(
-      @RequestAttribute(name = "hello") String who,
-      @RequestAttribute(name = "response") String response) {
-
-    return ResponseEntity.ok("hello " + who + ", with response " + response);
-  }
-}
diff --git a/saga-spring/src/test/java/org/apache/servicecomb/saga/spring/SagaRecoveryTest.java b/saga-spring/src/test/java/org/apache/servicecomb/saga/spring/SagaRecoveryTest.java
deleted file mode 100644
index 0d1e9c5a..00000000
--- a/saga-spring/src/test/java/org/apache/servicecomb/saga/spring/SagaRecoveryTest.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * 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.spring;
-
-import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
-import static com.github.tomakehurst.wiremock.client.WireMock.containing;
-import static com.github.tomakehurst.wiremock.client.WireMock.delete;
-import static com.github.tomakehurst.wiremock.client.WireMock.deleteRequestedFor;
-import static com.github.tomakehurst.wiremock.client.WireMock.exactly;
-import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
-import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
-import static com.github.tomakehurst.wiremock.client.WireMock.verify;
-import static java.util.Collections.singletonMap;
-
-import org.apache.servicecomb.saga.core.NoOpSagaRequest;
-import org.apache.servicecomb.saga.core.SagaRequestImpl;
-import org.apache.servicecomb.saga.core.SagaStartedEvent;
-import org.apache.servicecomb.saga.core.ToJsonFormat;
-import org.apache.servicecomb.saga.format.JacksonRestCompensation;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Primary;
-import org.springframework.context.annotation.Profile;
-import org.springframework.test.context.ActiveProfiles;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import com.github.tomakehurst.wiremock.junit.WireMockRule;
-
-import org.apache.servicecomb.saga.core.PersistentStore;
-import org.apache.servicecomb.saga.core.SagaEndedEvent;
-import org.apache.servicecomb.saga.core.SagaRequest;
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.apache.servicecomb.saga.core.SuccessfulSagaResponse;
-import org.apache.servicecomb.saga.core.TransactionAbortedEvent;
-import org.apache.servicecomb.saga.core.TransactionCompensatedEvent;
-import org.apache.servicecomb.saga.core.TransactionEndedEvent;
-import org.apache.servicecomb.saga.core.TransactionStartedEvent;
-import org.apache.servicecomb.saga.format.JacksonFallback;
-import org.apache.servicecomb.saga.format.JacksonRestTransaction;
-import org.apache.servicecomb.saga.format.SagaEventFormat;
-import org.apache.servicecomb.saga.spring.SagaRecoveryTest.EventPopulatingConfig;
-import wiremock.org.apache.http.HttpStatus;
-
-@RunWith(SpringRunner.class)
-@SpringBootTest(classes = {SagaSpringApplication.class, EventPopulatingConfig.class})
-@ActiveProfiles("recovery-test")
-public class SagaRecoveryTest {
-
-  @ClassRule
-  public static final WireMockRule wireMockRule = new WireMockRule(8090);
-
-  private static String request(final String name) {
-    return "  {\n"
-        + "    \"id\": \"request-" + name + "\",\n"
-        + "    \"type\": \"rest\",\n"
-        + "    \"serviceName\": \"localhost:8090\",\n"
-        + "    \"transaction\": {\n"
-        + "      \"method\": \"post\",\n"
-        + "      \"path\": \"/rest/" + name + "\",\n"
-        + "      \"params\": {\n"
-        + "        \"form\": {\n"
-        + "          \"foo\": \"" + name + "\"\n"
-        + "        }\n"
-        + "      }\n"
-        + "    },\n"
-        + "    \"compensation\": {\n"
-        + "      \"method\": \"delete\",\n"
-        + "      \"path\": \"/rest/" + name + "\",\n"
-        + "      \"params\": {\n"
-        + "        \"query\": {\n"
-        + "          \"bar\": \"" + name + "\"\n"
-        + "        }\n"
-        + "      }\n"
-        + "    }\n"
-        + "  }\n";
-  }
-
-  private static final String requestY = "[\n"
-      + request("yyy1")
-      + ","
-      + request("yyy2")
-      + ","
-      + request("yyy3")
-      + "]\n";
-
-  private static final String sagaY = "{\"policy\": \"ForwardRecovery\",\"requests\": " + requestY + "}";
-
-  @BeforeClass
-  public static void setUp() throws Exception {
-    stubFor(delete(urlPathEqualTo("/rest/yyy1"))
-        .withQueryParam("bar", containing("yyy1"))
-        .willReturn(
-            aResponse()
-                .withStatus(HttpStatus.SC_OK)
-                .withBody("success")));
-  }
-
-  @Test
-  public void recoverIncompleteSagasFromSagaLog() throws Exception {
-    verify(exactly(0), postRequestedFor(urlPathEqualTo("/rest/xxx")));
-
-    verify(exactly(0), postRequestedFor(urlPathEqualTo("/rest/yyy1")));
-    verify(exactly(1), deleteRequestedFor(urlPathEqualTo("/rest/yyy1")));
-
-    verify(exactly(0), postRequestedFor(urlPathEqualTo("/rest/yyy2")));
-    verify(exactly(0), deleteRequestedFor(urlPathEqualTo("/rest/yyy2")));
-
-    verify(exactly(0), postRequestedFor(urlPathEqualTo("/rest/yyy3")));
-    verify(exactly(0), deleteRequestedFor(urlPathEqualTo("/rest/yyy3")));
-  }
-
-  @Profile("recovery-test")
-  @Configuration
-  static class EventPopulatingConfig {
-
-    private static final String DONT_CARE = "{}";
-
-    private final SagaRequest request1 = sagaRequest("yyy1");
-    private final SagaRequest request2 = sagaRequest("yyy2");
-    private final SagaRequest request3 = sagaRequest("yyy3");
-
-    private final SagaResponse response1 = new SuccessfulSagaResponse("succeeded, yyy1");
-    private final SagaResponse response2 = new SuccessfulSagaResponse("succeeded, yyy2");
-
-    @Primary
-    @Bean
-    PersistentStore persistentStore(SagaEventRepo repo, ToJsonFormat toJsonFormat, SagaEventFormat sagaEventFormat) {
-      repo.save(new SagaEventEntity("xxx", SagaStartedEvent.class.getSimpleName(), DONT_CARE));
-      repo.save(new SagaEventEntity("xxx", TransactionStartedEvent.class.getSimpleName(), DONT_CARE));
-      repo.save(new SagaEventEntity("xxx", TransactionEndedEvent.class.getSimpleName(), DONT_CARE));
-      repo.save(new SagaEventEntity("xxx", SagaEndedEvent.class.getSimpleName(), DONT_CARE));
-
-      PersistentStore store = new JpaPersistentStore(repo, toJsonFormat, sagaEventFormat);
-
-      store.offer(new SagaStartedEvent("yyy", sagaY, NoOpSagaRequest.SAGA_START_REQUEST));
-      store.offer(new TransactionStartedEvent("yyy", request1));
-      store.offer(new TransactionEndedEvent("yyy", request1, response1));
-
-      store.offer(new TransactionStartedEvent("yyy", request2));
-      store.offer(new TransactionEndedEvent("yyy", request2, response2));
-
-      store.offer(new TransactionStartedEvent("yyy", request3));
-      store.offer(new TransactionAbortedEvent("yyy", request3, new RuntimeException("oops")));
-
-      store.offer(new TransactionCompensatedEvent("yyy", request2, response2));
-
-      return store;
-    }
-
-    private SagaRequestImpl sagaRequest(final String name) {
-      return new SagaRequestImpl(
-          "request-" + name,
-          "localhost:8080",
-          "rest",
-          new JacksonRestTransaction("/rest/" + name, "post", singletonMap("query", singletonMap("foo", name))),
-          new JacksonRestCompensation("rest/" + name, "delete", singletonMap("query", singletonMap("bar", name))),
-          JacksonFallback.NOP_TRANSPORT_AWARE_FALLBACK);
-    }
-  }
-}
diff --git a/saga-spring/src/test/java/org/apache/servicecomb/saga/spring/SagaServiceDiscoveryTest.java b/saga-spring/src/test/java/org/apache/servicecomb/saga/spring/SagaServiceDiscoveryTest.java
deleted file mode 100644
index 7ca683c1..00000000
--- a/saga-spring/src/test/java/org/apache/servicecomb/saga/spring/SagaServiceDiscoveryTest.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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.spring;
-
-import static io.restassured.RestAssured.given;
-import static io.restassured.http.ContentType.TEXT;
-import static io.servicecomb.serviceregistry.client.LocalServiceRegistryClientImpl.LOCAL_REGISTRY_FILE_KEY;
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-import org.junit.BeforeClass;
-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.ActiveProfiles;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import org.apache.servicecomb.saga.core.TransactionEndedEvent;
-
-@SuppressWarnings("unchecked")
-@RunWith(SpringRunner.class)
-@SpringBootTest(classes = SagaSpringApplication.class)
-@ActiveProfiles("servicecomb")
-public class SagaServiceDiscoveryTest {
-
-  private static final String requests = "[\n"
-      + "  {\n"
-      + "    \"id\": \"request-aaa\",\n"
-      + "    \"type\": \"rest\",\n"
-      + "    \"serviceName\": \"saga-service\",\n"
-      + "    \"transaction\": {\n"
-      + "      \"method\": \"post\",\n"
-      + "      \"path\": \"/rest/usableResource\",\n"
-      + "      \"params\": {\n"
-      + "        \"form\": {\n"
-      + "          \"hello\": \"world\"\n"
-      + "        }"
-      + "      }\n"
-      + "    },\n"
-      + "    \"compensation\": {\n"
-      + "      \"method\": \"delete\",\n"
-      + "      \"path\": \"/rest/usableResource\",\n"
-      + "      \"params\": {\n"
-      + "        \"query\": {\n"
-      + "          \"foo\": \"bar\"\n"
-      + "        }\n"
-      + "      }\n"
-      + "    }\n"
-      + "  }\n"
-      + "]\n";
-
-  private static final String sagaDefinition = "{\"policy\": \"ForwardRecovery\",\"requests\": " + requests + "}";
-
-  @Autowired
-  private SagaEventRepo sagaEventRepo;
-
-
-  @BeforeClass
-  public static void setUpClass() throws Exception {
-    setUpLocalRegistry();
-  }
-
-  private static void setUpLocalRegistry() {
-    ClassLoader loader = Thread.currentThread().getContextClassLoader();
-    URL resource = loader.getResource("registry.yaml");
-    System.setProperty(LOCAL_REGISTRY_FILE_KEY, resource.getPath());
-  }
-
-  @Test
-  public void processRequestByServiceDiscovery() throws Exception {
-    given()
-        .contentType(TEXT)
-        .body(sagaDefinition)
-        .when()
-        .post("http://localhost:8080/requests")
-        .then()
-        .statusCode(200)
-        .body(is("success"));
-
-    List<SagaEventEntity> events = new ArrayList<>();
-    sagaEventRepo.findAll().forEach(events::add);
-
-    Optional<SagaEventEntity> eventEntity = events.stream()
-        .filter(entity -> entity.type().equals(TransactionEndedEvent.class.getSimpleName()))
-        .findFirst();
-
-    assertThat(eventEntity.isPresent(), is(true));
-    assertThat(eventEntity.get().contentJson(), containsString("hello world, with response {}"));
-  }
-
-}
diff --git a/saga-spring/src/test/java/org/apache/servicecomb/saga/spring/SagaSpringApplicationTestBase.java b/saga-spring/src/test/java/org/apache/servicecomb/saga/spring/SagaSpringApplicationTestBase.java
deleted file mode 100644
index 65544695..00000000
--- a/saga-spring/src/test/java/org/apache/servicecomb/saga/spring/SagaSpringApplicationTestBase.java
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * 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.spring;
-
-import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
-import static com.github.tomakehurst.wiremock.client.WireMock.containing;
-import static com.github.tomakehurst.wiremock.client.WireMock.exactly;
-import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
-import static com.github.tomakehurst.wiremock.client.WireMock.resetAllRequests;
-import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
-import static com.github.tomakehurst.wiremock.client.WireMock.verify;
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.Matchers.containsInAnyOrder;
-import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
-import static org.junit.Assert.assertThat;
-import static org.springframework.http.MediaType.TEXT_PLAIN;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-import java.net.URLEncoder;
-
-import org.apache.servicecomb.saga.spring.SagaController.SagaExecutionDetail;
-import org.apache.servicecomb.saga.spring.SagaController.SagaExecutionQueryResult;
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.hamcrest.TypeSafeMatcher;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
-import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.test.web.servlet.MockMvc;
-import org.springframework.test.web.servlet.MvcResult;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.github.tomakehurst.wiremock.client.WireMock;
-import com.github.tomakehurst.wiremock.junit.WireMockRule;
-
-import wiremock.org.apache.http.HttpStatus;
-
-@SuppressWarnings("unchecked")
-@RunWith(SpringRunner.class)
-@AutoConfigureMockMvc
-public class SagaSpringApplicationTestBase {
-
-  private static final ObjectMapper mapper = new ObjectMapper();
-
-  @ClassRule
-  public static final WireMockRule wireMockRule = new WireMockRule(8090);
-
-  private static final String requests = "[\n"
-      + "  {\n"
-      + "    \"id\": \"request-aaa\",\n"
-      + "    \"type\": \"rest\",\n"
-      + "    \"serviceName\": \"localhost:8090\",\n"
-      + "    \"transaction\": {\n"
-      + "      \"method\": \"post\",\n"
-      + "      \"path\": \"/rest/as\",\n"
-      + "      \"params\": {\n"
-      + "        \"form\": {\n"
-      + "          \"foo\": \"as\"\n"
-      + "        }\n"
-      + "      }\n"
-      + "    },\n"
-      + "    \"compensation\": {\n"
-      + "      \"method\": \"delete\",\n"
-      + "      \"path\": \"/rest/as\",\n"
-      + "      \"params\": {\n"
-      + "        \"query\": {\n"
-      + "          \"bar\": \"as\"\n"
-      + "        }\n"
-      + "      }\n"
-      + "    }\n"
-      + "  },\n"
-      + "  {\n"
-      + "    \"id\": \"request-bbb\",\n"
-      + "    \"type\": \"rest\",\n"
-      + "    \"serviceName\": \"localhost:8090\",\n"
-      + "    \"transaction\": {\n"
-      + "      \"method\": \"post\",\n"
-      + "      \"path\": \"/rest/as\",\n"
-      + "      \"params\": {\n"
-      + "        \"form\": {\n"
-      + "          \"foo\": \"as\"\n"
-      + "        }\n"
-      + "      }\n"
-      + "    },\n"
-      + "    \"compensation\": {\n"
-      + "      \"method\": \"delete\",\n"
-      + "      \"path\": \"/rest/as\",\n"
-      + "      \"params\": {\n"
-      + "        \"query\": {\n"
-      + "          \"bar\": \"as\"\n"
-      + "        }\n"
-      + "      }\n"
-      + "    },\n"
-      + "    \"parents\": [\"request-aaa\"]\n"
-      + "  }\n"
-      + "]\n";
-
-  private static final String failRequests = "[\n"
-      + "  {\n"
-      + "    \"id\": \"request-aaa\",\n"
-      + "    \"type\": \"rest\",\n"
-      + "    \"serviceName\": \"localhost:8090\",\n"
-      + "    \"transaction\": {\n"
-      + "      \"method\": \"post\",\n"
-      + "      \"path\": \"/rest/bs\",\n"
-      + "      \"params\": {\n"
-      + "        \"form\": {\n"
-      + "          \"foo\": \"bs\"\n"
-      + "        }\n"
-      + "      }\n"
-      + "    },\n"
-      + "    \"compensation\": {\n"
-      + "      \"method\": \"delete\",\n"
-      + "      \"path\": \"/rest/bs\",\n"
-      + "      \"params\": {\n"
-      + "        \"query\": {\n"
-      + "          \"bar\": \"bs\"\n"
-      + "        }\n"
-      + "      }\n"
-      + "    }\n"
-      + "  }\n"
-      + "]\n";
-
-  private static final String sagaDefinition = "{\"policy\": \"ForwardRecovery\",\"requests\": " + requests + "}";
-  private static final String sagaFailDefinition =
-      "{\"policy\": \"BackwardRecovery\",\"requests\": " + failRequests + "}";
-
-  @Autowired
-  private MockMvc mockMvc;
-
-  @Autowired
-  private SagaEventRepo sagaEventRepo;
-
-  @BeforeClass
-  public static void setUp() throws Exception {
-    stubFor(WireMock.post(urlPathEqualTo("/rest/as"))
-        .withRequestBody(containing("foo=as&response=" + URLEncoder.encode("{}", "UTF-8")))
-        .willReturn(
-            aResponse()
-                .withStatus(HttpStatus.SC_OK)
-                .withBody("{\n"
-                    + "  \"body\": \"success\",\n"
-                    + "  \"sagaChildren\": [\"none\"]\n"
-                    + "}")));
-
-    stubFor(WireMock.post(urlPathEqualTo("/rest/bs"))
-        .withRequestBody(containing("foo=bs"))
-        .willReturn(
-            aResponse()
-                .withStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR)
-                .withBody("process failed")));
-  }
-
-  @Before
-  public void tearUp() {
-    resetAllRequests();
-    sagaEventRepo.deleteAll();
-  }
-
-  @Test
-  public void testBadFormatRequest() throws Exception {
-    try {
-      mockMvc.perform(
-          post("/requests/")
-              .contentType(TEXT_PLAIN)
-              .content("xxxx"))
-          .andExpect(status().is(HttpStatus.SC_BAD_REQUEST))
-          .andExpect(content().string(containsString("illegal request content")));
-    } catch (org.springframework.web.util.NestedServletException ex) {
-      assertThat(ex.getMessage(), containsString("Failed to interpret JSON xxxx"));
-    }
-  }
-
-  @Test
-  public void testFailedRequest() throws Exception {
-    try {
-      mockMvc.perform(
-          post("/requests/")
-              .contentType(TEXT_PLAIN)
-              .content(sagaFailDefinition))
-          .andExpect(status().is(HttpStatus.SC_INTERNAL_SERVER_ERROR))
-          .andExpect(content().string(containsString("transaction failed")));
-    } catch (org.springframework.web.util.NestedServletException ex) {
-      assertThat(ex.getMessage(), containsString(
-          "The remote service returned with status code 500, reason Server Error"));
-    }
-
-    MvcResult resultJson = mockMvc.perform(get("/requests")
-        .param("pageIndex", "0")
-        .param("pageSize", "10")
-        .param("startTime", "NaN-NaN-NaN NaN:NaN:NaN")
-        .param("endTime", "NaN-NaN-NaN NaN:NaN:NaN"))
-        .andExpect(status().isOk()).andReturn();
-    SagaExecutionQueryResult result = mapper
-        .readValue(resultJson.getResponse().getContentAsString(), SagaExecutionQueryResult.class);
-    assertThat(result.requests.size(), is(1));
-
-    String sagaId = result.requests.get(0).sagaId;
-
-    MvcResult detailJson = mockMvc.perform(get("/requests/" + sagaId)).andExpect(status().isOk())
-        .andReturn();
-    SagaExecutionDetail executionDetail = mapper
-        .readValue(detailJson.getResponse().getContentAsString(), SagaExecutionDetail.class);
-
-    assertThat(executionDetail.router.keySet(), containsInAnyOrder("saga-start", "request-aaa"));
-    assertThat(executionDetail.status.get("request-aaa"), is("Failed"));
-    assertThat(executionDetail.error.size(), is(1));
-  }
-
-  @Test
-  public void processRequestByRest() throws Exception {
-    mockMvc.perform(
-        post("/requests/")
-            .contentType(TEXT_PLAIN)
-            .content(sagaDefinition))
-        .andExpect(status().isOk());
-
-    verify(exactly(1), postRequestedFor(urlPathEqualTo("/rest/as")));
-
-    Iterable<SagaEventEntity> events = sagaEventRepo.findAll();
-
-    assertThat(events, contains(
-        eventWith(1L, "SagaStartedEvent"),
-        eventWith(2L, "TransactionStartedEvent"),
-        eventWith(3L, "TransactionEndedEvent"),
-        eventWith(4L, "SagaEndedEvent")
-    ));
-
-    MvcResult resultJson = mockMvc.perform(get("/requests")
-        .param("pageIndex", "0")
-        .param("pageSize", "10")
-        .param("startTime", "NaN-NaN-NaN NaN:NaN:NaN")
-        .param("endTime", "NaN-NaN-NaN NaN:NaN:NaN"))
-        .andExpect(status().isOk()).andReturn();
-    SagaExecutionQueryResult result = mapper
-        .readValue(resultJson.getResponse().getContentAsString(), SagaExecutionQueryResult.class);
-    assertThat(result.requests.size(), is(1));
-
-    String sagaId = result.requests.get(0).sagaId;
-
-    MvcResult detailJson = mockMvc.perform(get("/requests/" + sagaId)).andExpect(status().isOk())
-        .andReturn();
-    SagaExecutionDetail executionDetail = mapper
-        .readValue(detailJson.getResponse().getContentAsString(), SagaExecutionDetail.class);
-
-    assertThat(executionDetail.router.keySet(), containsInAnyOrder("saga-start", "request-bbb", "request-aaa"));
-    assertThat(executionDetail.status.get("request-aaa"), is("OK"));
-    assertThat(executionDetail.error.size(), is(0));
-  }
-
-  @Test
-  public void queryRequestsWithBadParameter() throws Exception {
-    try {
-      mockMvc.perform(get("/requests")
-          .param("pageIndex", "xxx")
-          .param("pageSize", "xxx")
-          .param("startTime", "NaN-NaN-NaN NaN:NaN:NaN")
-          .param("endTime", "NaN-NaN-NaN NaN:NaN:NaN"))
-          .andExpect(status().is(HttpStatus.SC_BAD_REQUEST));
-    } catch (org.springframework.web.util.NestedServletException ex) {
-      assertThat(ex.getMessage(), containsString("illegal request content"));
-    }
-
-    try {
-      mockMvc.perform(get("/requests")
-          .param("pageIndex", "0")
-          .param("pageSize", "10")
-          .param("startTime", "x0")
-          .param("endTime", "x1"))
-          .andExpect(status().is(HttpStatus.SC_BAD_REQUEST));
-    } catch (org.springframework.web.util.NestedServletException ex) {
-      assertThat(ex.getMessage(), containsString("illegal request content"));
-    }
-  }
-
-  @Test
-  public void queryRequestsWithNANParameter() throws Exception {
-    mockMvc.perform(
-        post("/requests/")
-            .contentType(TEXT_PLAIN)
-            .content(sagaDefinition))
-        .andExpect(status().isOk());
-
-    MvcResult resultJson = mockMvc.perform(get("/requests")
-        .param("pageIndex", "0")
-        .param("pageSize", "10")
-        .param("startTime", "NaN-NaN-NaN NaN:NaN:NaN")
-        .param("endTime", "NaN-NaN-NaN NaN:NaN:NaN"))
-        .andExpect(status().is(HttpStatus.SC_OK)).andReturn();
-    SagaExecutionQueryResult result = mapper
-        .readValue(resultJson.getResponse().getContentAsString(), SagaExecutionQueryResult.class);
-    assertThat(result.requests.size(), is(1));
-
-    resultJson = mockMvc.perform(get("/requests")
-        .param("pageIndex", "0")
-        .param("pageSize", "10")
-        .param("startTime", "2000-1-1 00:00:00")
-        .param("endTime", "NaN-NaN-NaN NaN:NaN:NaN"))
-        .andExpect(status().is(HttpStatus.SC_OK)).andReturn();
-    result = mapper
-        .readValue(resultJson.getResponse().getContentAsString(), SagaExecutionQueryResult.class);
-    assertThat(result.requests.size(), is(1));
-
-    resultJson = mockMvc.perform(get("/requests")
-        .param("pageIndex", "0")
-        .param("pageSize", "10")
-        .param("startTime", "NaN-NaN-NaN NaN:NaN:NaN")
-        .param("endTime", "9999-12-31 12:59:59"))
-        .andExpect(status().is(HttpStatus.SC_OK)).andReturn();
-    result = mapper
-        .readValue(resultJson.getResponse().getContentAsString(), SagaExecutionQueryResult.class);
-    assertThat(result.requests.size(), is(1));
-
-    try {
-      mockMvc.perform(get("/requests")
-          .param("pageIndex", "0")
-          .param("pageSize", "10")
-          .param("startTime", "9999-12-31 12:59:59")
-          .param("endTime", "2000-1-1 00:00:00"))
-          .andExpect(status().is(HttpStatus.SC_BAD_REQUEST));
-    } catch (org.springframework.web.util.NestedServletException ex) {
-      assertThat(ex.getMessage(), containsString("illegal request content"));
-    }
-  }
-
-  @Test
-  public void allEvents() throws Exception {
-    mockMvc.perform(
-        post("/requests/")
-            .contentType(TEXT_PLAIN)
-            .content(sagaDefinition))
-        .andExpect(status().isOk());
-    mockMvc.perform(get("/events")).andExpect(status().isOk())
-        .andExpect(content().string(containsString("SagaStartedEvent")))
-        .andExpect(content().string(containsString("request-aaa")))
-        .andExpect(content().string(containsString("request-bbb")))
-        .andExpect(content().string(containsString("SagaEndedEvent")));
-  }
-
-
-  private Matcher<SagaEventEntity> eventWith(
-      long eventId,
-      String type) {
-
-    return new TypeSafeMatcher<SagaEventEntity>() {
-      @Override
-      protected boolean matchesSafely(SagaEventEntity event) {
-        return eventId == event.id() && event.type().equals(type);
-      }
-
-      @Override
-      protected void describeMismatchSafely(SagaEventEntity item, Description mismatchDescription) {
-        mismatchDescription.appendText(item.toString());
-      }
-
-      @Override
-      public void describeTo(Description description) {
-        description.appendText(
-            "SagaEventEntity {"
-                + "id=" + eventId
-                + ", type=" + type);
-      }
-    };
-  }
-}
diff --git a/saga-spring/src/test/resources/data.sql b/saga-spring/src/test/resources/data.sql
deleted file mode 100644
index 5cdb7d92..00000000
--- a/saga-spring/src/test/resources/data.sql
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.
- */
-
-DROP TABLE IF EXISTS SagaEventEntity;
-
-CREATE TABLE `SagaEventEntity` (
-  `id` bigint NOT NULL AUTO_INCREMENT,
-  `sagaId` varchar(36) NOT NULL,
-  `creationTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
-  `type` varchar(50) NOT NULL,
-  `contentJson` clob NOT NULL DEFAULT '{}',
-  PRIMARY KEY (`id`)
-) DEFAULT CHARSET=utf8;
-
- CREATE INDEX running_sagas_index ON sagaEventEntity(sagaId, type);
diff --git a/saga-spring/src/test/resources/log4j2-test.xml b/saga-spring/src/test/resources/log4j2-test.xml
deleted file mode 100644
index 58924c68..00000000
--- a/saga-spring/src/test/resources/log4j2-test.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?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>
-    <Root level="info">
-      <AppenderRef ref="Console"/>
-    </Root>
-  </Loggers>
-</Configuration>
diff --git a/saga-spring/src/test/resources/registry.yaml b/saga-spring/src/test/resources/registry.yaml
deleted file mode 100644
index 82752b44..00000000
--- a/saga-spring/src/test/resources/registry.yaml
+++ /dev/null
@@ -1,23 +0,0 @@
-## ---------------------------------------------------------------------------
-## 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.
-## ---------------------------------------------------------------------------
-saga-service:
-  - id: "001"
-    version: "0.0.1"
-    appid: saga
-    instances:
-      - endpoints:
-        - rest://127.0.0.1:8080?sslEnabled=false
diff --git a/saga-web/pom.xml b/saga-web/pom.xml
deleted file mode 100644
index 94b1ec06..00000000
--- a/saga-web/pom.xml
+++ /dev/null
@@ -1,130 +0,0 @@
-<?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</artifactId>
-    <groupId>org.apache.servicecomb.saga</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>saga-web</artifactId>
-  <name>Saga::Web</name>
-
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.apache.commons</groupId>
-        <artifactId>commons-lang3</artifactId>
-        <version>3.6</version>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb</groupId>
-        <artifactId>spring-boot-starter-provider</artifactId>
-        <version>${java.chassis.version}</version>
-        <exclusions>
-          <exclusion>
-            <groupId>com.google.code.findbugs</groupId>
-            <artifactId>annotations</artifactId>
-          </exclusion>
-        </exclusions>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb</groupId>
-        <artifactId>spring-boot-starter-discovery</artifactId>
-        <version>${java.chassis.version}</version>
-        <exclusions>
-          <exclusion>
-            <groupId>com.google.code.findbugs</groupId>
-            <artifactId>annotations</artifactId>
-          </exclusion>
-        </exclusions>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb</groupId>
-        <artifactId>java-chassis-dependencies</artifactId>
-        <version>${java.chassis.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-      <dependency>
-        <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot-dependencies</artifactId>
-        <version>${spring.boot.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.servicecomb</groupId>
-      <artifactId>spring-boot-starter-discovery</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.servicecomb</groupId>
-      <artifactId>spring-boot-starter-servicecomb</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.servicecomb</groupId>
-      <artifactId>spring-cloud-zuul</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-web/src/main/java/org/apache/servicecomb/saga/web/SagaWebApplication.java b/saga-web/src/main/java/org/apache/servicecomb/saga/web/SagaWebApplication.java
deleted file mode 100644
index a095d684..00000000
--- a/saga-web/src/main/java/org/apache/servicecomb/saga/web/SagaWebApplication.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.web;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
-
-import io.servicecomb.springboot.starter.provider.EnableServiceComb;
-
-@SpringBootApplication
-@EnableZuulProxy
-@EnableServiceComb
-public class SagaWebApplication {
-
-  public static void main(String[] args) {
-    SpringApplication.run(SagaWebApplication.class, args);
-  }
-}
diff --git a/saga-web/src/main/resources/application.yaml b/saga-web/src/main/resources/application.yaml
deleted file mode 100644
index 3bb08342..00000000
--- a/saga-web/src/main/resources/application.yaml
+++ /dev/null
@@ -1,29 +0,0 @@
-## ---------------------------------------------------------------------------
-## 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.
-## ---------------------------------------------------------------------------
-
-zuul:
-  routes:
-    saga-service:
-      serviceId: saga-service
-
-# disable netflix eureka since it's not used for service discovery
-ribbon:
-  eureka:
-    enabled: false
-
-server:
-  port: 8888
\ No newline at end of file
diff --git a/saga-web/src/main/resources/microservice.yaml b/saga-web/src/main/resources/microservice.yaml
deleted file mode 100644
index 399fd028..00000000
--- a/saga-web/src/main/resources/microservice.yaml
+++ /dev/null
@@ -1,31 +0,0 @@
-## ---------------------------------------------------------------------------
-## 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.
-## ---------------------------------------------------------------------------
-
-# all interconnected microservices must belong to an application wth the same ID
-APPLICATION_ID: saga
-service_description:
-# name of the declaring microservice
-  name: saga-web
-  version: 0.0.1
-cse:
-  service:
-    registry:
-      address: http://sc.servicecomb.io:30100
-
-servicecomb:
-  tracing:
-    enabled: false
diff --git a/saga-web/src/main/resources/static/css/request.css b/saga-web/src/main/resources/static/css/request.css
deleted file mode 100644
index a7169f0a..00000000
--- a/saga-web/src/main/resources/static/css/request.css
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- *  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.
- */
-
-.loading,
-.loading::after {
-  position: absolute;
-  left: 50%;
-  top: 50%;
-  transform: translate(-50%, -50%);
-  -webkit-transform: translate(-50%, -50%);
-}
-
-.loading,
-.loading span {
-  width: 62px;
-  height: 62px;
-  border-radius: 62px;
-}
-
-.loading {
-  border: 5px solid #d0cecc;
-}
-
-.loading span {
-  display: block;
-  transform: rotate(0);
-  -webkit-transform: rotate(0);
-  -webkit-animation: loading 600ms linear infinite;
-  animation: loading 600ms linear infinite;
-  background-size: 17px 8px;
-  background-position: 31px 1px;
-}
-
-.loading::after {
-  content: "loading";
-  display: block;
-  width: 50px;
-  height: 50px;
-  line-height: 50px;
-  text-align: center;
-  font-style: italic;
-  color: #fff;
-  font-size: 12px;
-  border-radius: 50px;
-  background: #d0cecc;
-}
-
-.loading-data img {
-  width: 100%;
-  max-width: 100%;
-  background-size: cover;
-}
diff --git a/saga-web/src/main/resources/static/css/style.css b/saga-web/src/main/resources/static/css/style.css
deleted file mode 100644
index b1b67769..00000000
--- a/saga-web/src/main/resources/static/css/style.css
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *  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.
- */
-
-ul#nav {
-  width: 100%;
-  height: 30px;
-  background: #00A2CA;
-  margin: 0 auto
-}
-
-ul#nav li {
-  display: inline;
-  height: 30px
-}
-
-ul#nav li a {
-  display: inline-block;
-  padding: 0 20px;
-  height: 30px;
-  line-height: 30px;
-  color: #FFF;
-  font-size: 16px
-}
-
-ul#nav li a:hover {
-  background: #0095BB
-}
\ No newline at end of file
diff --git a/saga-web/src/main/resources/static/detail.html b/saga-web/src/main/resources/static/detail.html
deleted file mode 100755
index ef7cbe08..00000000
--- a/saga-web/src/main/resources/static/detail.html
+++ /dev/null
@@ -1,174 +0,0 @@
-<!DOCTYPE HTML>
-<!--
-  ~ 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.
-  -->
-<html>
-<head>
-  <title>Detail</title>
-  <script src="http://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
-  <script src="https://cdnjs.cloudflare.com/ajax/libs/raphael/1.3.2/raphael-min.js" integrity="sha256-5C/soUzPY/Tqibm8m0ScOsVh++6jF/FIe7EwzCJNc9I=" crossorigin="anonymous"></script>
-  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/graphdracula/1.0.3/dracula.min.js"></script>
-  <script type="text/javascript">
-    var redraw;
-	var height = 600;
-	var width = 600;
-
-    function getQueryString(name, url) {
-      var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
-      var r = url.match(reg);
-      if (r != null) {
-        return unescape(r[2]);
-      }
-      return null;
-    }
-
-    var sagaId = "";
-    if (location.href.split('?').length > 1) {
-      var par = location.href.split('?')[1];
-      sagaId = getQueryString("sagaId", par);
-    }
-    var url = "/saga-service/requests/" + sagaId;
-    var render = function (r, n) {
-      /* the Raphael set is obligatory, containing all you want to display */
-      var set = r.set().push(
-          /* custom objects go here */
-          r.rect(n.point[0] - 30, n.point[1] - 13, 60, 44).attr(
-              {"fill": "#5b9bd5", r: "12px", "stroke-width": n.distance == 0 ? "3px" : "1px"})).push(
-          r.text(n.point[0], n.point[1] + 10, (n.label || n.id)));
-      return set;
-    };
-
-    var render_false = function (r, n) {
-      /* the Raphael set is obligatory, containing all you want to display */
-      var set = r.set().push(
-          /* custom objects go here */
-          r.rect(n.point[0] - 30, n.point[1] - 13, 60, 44).attr(
-              {"fill": "#d16d2a", r: "12px", "stroke-width": n.distance == 0 ? "3px" : "1px"})).push(
-          r.text(n.point[0], n.point[1] + 10, (n.label || n.id)));
-      return set;
-    };
-
-    var render_no = function (r, n) {
-      /* the Raphael set is obligatory, containing all you want to display */
-      var set = r.set().push(
-          /* custom objects go here */
-          r.rect(n.point[0] - 30, n.point[1] - 13, 60, 44).attr(
-              {"fill": "#f2f2f2", r: "12px", "stroke-width": n.distance == 0 ? "3px" : "1px"})).push(
-          r.text(n.point[0], n.point[1] + 10, (n.label || n.id)));
-      return set;
-    };
-
-    var g = new Graph();
-    /* modify the edge creation to attach random weights */
-    g.edgeFactory.build = function (source, target) {
-      var e = jQuery.extend(true, {}, this.template);
-      e.source = source;
-      e.target = target;
-      e.style.label = e.weight = Math.floor(Math.random() * 10) + 1;
-      return e;
-    }
-
-    var render_st = function (r, n) {
-      /* the Raphael set is obligatory, containing all you want to display */
-      var set = r.set().push(
-          /* custom objects go here */
-          r.rect(n.point[0] - 30, n.point[1] - 13, 60, 44).attr(
-              {"fill": "#7b92f1", r: "22px", "stroke-width": n.distance == 0 ? "3px" : "1px"})).push(
-          r.text(n.point[0], n.point[1] + 10, (n.label || n.id)));
-      return set;
-    };
-
-    window.onload = function () {
-      $.ajax({
-        type: 'GET',
-        url: url,
-        dataType: "json",
-        success: function (datas) {
-          console.log(datas);
-          //var datas = {"router":{"request-aaa":["request-bbb"],"saga-start":["request-aaa"],"request-bbb":["saga-end"]},"status":{"request-aaa":"OK","request-bbb":"OK"},"error":{}};
-          var datas_status = datas.status;
-          $.each(datas.router,function(key,value){
-				$.each(value,function(k,val){
-					if(datas_status[key] == 'Failed'){
-						if(key.indexOf("saga-start") >= 0){
-							g.addNode(key, {render:render_st});
-						}else if(val.indexOf("saga-end") >= 0){
-							g.addNode(val, {render:render_st});
-						}
-						g.addNode(key, {render:render_no});
-						g.addNode(val, {render:render_no});
-						
-						g.addEdge(key, val, {
-							stroke: '#adadad',
-							//fill: '#f2f2f2',
-							label: '',
-							directed : true
-						});
-					}else if(datas_status[val] == 'Failed'){
-						if(key.indexOf("saga-start") >= 0){
-							g.addNode(key, {render:render_st});
-						}else if(val.indexOf("saga-end") >= 0){
-							g.addNode(val, {render:render_st});
-						}
-						g.addNode(key, {render:render});
-						g.addNode(val, {render:render_false});
-						
-						g.addEdge(key, val, {
-							stroke: '#adadad',
-							//fill: '#f2f2f2',
-							label: '',
-							directed : true
-						});
-					}else{
-						if(key.indexOf("saga-start") >= 0){
-							g.addNode(key, {render:render_st});
-						}else if(val.indexOf("saga-end") >= 0){
-							g.addNode(val, {render:render_st});
-						}
-						g.addNode(key, {render:render});
-						g.addNode(val, {render:render});
-						
-						g.addEdge(key, val, {
-							stroke: '#5b9bd5',
-							//fill: '#5b9bd5',
-							label: '',
-							directed : true
-						});	
-					}
-				})
-			})
-
-          /* layout the graph using the Spring layout implementation */
-          var layouter = new Graph.Layout.Spring(g);
-          layouter.layout();
-
-          /* draw the graph using the RaphaelJS draw implementation */
-          var renderer = new Graph.Renderer.Raphael('canvas', g, width, height);
-          renderer.draw();
-
-          redraw = function () {
-            layouter.layout();
-            renderer.draw();
-          };
-        }
-      });
-    };
-  </script>
-</head>
-<body>
-<div id="canvas" style="height: 600px; width: 100%;text-align: center;"></div>
-</body>
-</html>
diff --git a/saga-web/src/main/resources/static/index.html b/saga-web/src/main/resources/static/index.html
deleted file mode 100644
index 8dd88777..00000000
--- a/saga-web/src/main/resources/static/index.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE HTML>
-<!--
-  ~ 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.
-  -->
-<html>
-<head>
-  <title>Saga Web</title>
-  <link rel="stylesheet" href="css/style.css" type="text/css">
-</head>
-<body>
-<ul id="nav">
-  <li><a href="request.html">Request</a></li>
-  <li><a href="result.html">Result</a></li>
-  <li><a href="#">About</a></li>
-</ul>
-
-</body>
-</html>
diff --git a/saga-web/src/main/resources/static/js/date.js b/saga-web/src/main/resources/static/js/date.js
deleted file mode 100644
index 83f0b5c8..00000000
--- a/saga-web/src/main/resources/static/js/date.js
+++ /dev/null
@@ -1,660 +0,0 @@
-?/*
- *  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.
- */
-
-var cal;
-var isFocus = false; // ?????
-function SetDate(obj, strFormat) {
-
-  var date = new Date();
-  var by = date.getFullYear() - 50; // ??? ? 50??
-  var ey = date.getFullYear() + 20; // ??? ? 20??
-  // ????????1????
-  cal = (cal == null) ? new Calendar(by, ey, 1, strFormat)
-      : (cal.dateFormatStyle == strFormat ? cal : new Calendar(by, ey, 1,
-          strFormat));
-  cal.show(obj);
-}
-
-/**/
-/* ???? */
-String.prototype.toDate = function (style) {
-  var y = this.substring(style.indexOf('y'), style.lastIndexOf('y') + 1);// ?
-  var m = this.substring(style.indexOf('M'), style.lastIndexOf('M') + 1);// ?
-  var d = this.substring(style.indexOf('d'), style.lastIndexOf('d') + 1);// ?
-  var h = this.substring(style.indexOf('h'), style.lastIndexOf('h') + 1);// ?
-  var i = this.substring(style.indexOf('m'), style.lastIndexOf('m') + 1);// ?
-  var s = this.substring(style.indexOf('s'), style.lastIndexOf('s') + 1);// ?
-  if (isNaN(y)) {
-    y = new Date().getFullYear();
-  }
-  if (isNaN(m)) {
-    m = new Date().getMonth();
-  }
-  if (isNaN(d)) {
-    d = new Date().getDate();
-  }
-  if (isNaN(h)) {
-    h = new Date().getHours();
-  }
-  if (isNaN(i)) {
-    i = new Date().getMinutes();
-  }
-  if (isNaN(s)) {
-    s = new Date().getSeconds();
-  }
-  var dt;
-  eval("dt = new Date('" + y + "', '" + (m - 1) + "','" + d + "','" + h
-      + "','" + i + "','" + s + "')");
-  return dt;
-}
-/**/
-/* ????? */
-Date.prototype.format = function (style) {
-  var o = {
-    "M+": this.getMonth() + 1, // month
-    "d+": this.getDate(), // day
-    "h+": this.getHours(), // hour
-    "m+": this.getMinutes(), // minute
-    "s+": this.getSeconds(), // second
-    "w+": "???????".charAt(this.getDay()), // week
-    "q+": Math.floor((this.getMonth() + 3) / 3), // quarter
-    "S": this.getMilliseconds()
-    // millisecond
-  }
-  if (/(y+)/.test(style)) {
-    style = style.replace(RegExp.$1, (this.getFullYear() + "")
-    .substr(4 - RegExp.$1.length));
-  }
-  for (var k in o) {
-    if (new RegExp("(" + k + ")").test(style)) {
-      style = style.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k]
-          : ("00" + o[k]).substr(("" + o[k]).length));
-    }
-  }
-  return style;
-};
-
-/**/
-
-/*
-	 * ??? @param beginYear 1990 @param endYear 2010 @param lang 0(??)|1(??)
-	 * ????? @param dateFormatStyle "yyyy-MM-dd";
-	 */
-function Calendar(beginYear, endYear, lang, dateFormatStyle) {
-  this.beginYear = 1990;
-  this.endYear = 2010;
-  this.lang = 0; // 0(??) | 1(??)
-  this.dateFormatStyle = "yyyy-MM-dd";
-
-  if (beginYear != null && endYear != null) {
-    this.beginYear = beginYear;
-    this.endYear = endYear;
-  }
-  if (lang != null) {
-    this.lang = lang
-  }
-
-  if (dateFormatStyle != null) {
-    this.dateFormatStyle = dateFormatStyle
-  }
-
-  this.dateControl = null;
-  this.panel = this.getElementById("calendarPanel");
-  this.container = this.getElementById("ContainerPanel");
-  this.form = null;
-
-  this.date = new Date();
-  this.year = this.date.getFullYear();
-  this.month = this.date.getMonth();
-
-  this.colors = {
-    "cur_word": "#FFFFFF", // ????????
-    "cur_bg": "#83A6F4", // ??????????
-    "sel_bg": "#FFCCCC", // ?????????????
-    "sun_word": "#FF0000", // ???????
-    "sat_word": "#0000FF", // ???????
-    "td_word_light": "#333333", // ???????
-    "td_word_dark": "#CCCCCC", // ???????
-    "td_bg_out": "#EFEFEF", // ??????
-    "td_bg_over": "#FFCC00", // ??????
-    "tr_word": "#FFFFFF", // ???????
-    "tr_bg": "#666666", // ??????
-    "input_border": "#CCCCCC", // input???????
-    "input_bg": "#EFEFEF" // input??????
-  }
-
-  this.draw();
-  this.bindYear();
-  this.bindMonth();
-  this.changeSelect();
-  this.bindData();
-}
-
-/**/
-/*
-	 * ????????????????
-	 */
-Calendar.language = {
-  "year": [[""], [""]],
-  "months": [
-    ["??", "??", "??", "??", "??", "??", "??", "??", "??", "??",
-      "???", "???"],
-    ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP",
-      "OCT", "NOV", "DEC"]],
-  "weeks": [["?", "?", "?", "?", "?", "?", "?"],
-    ["SUN", "MON", "TUR", "WED", "THU", "FRI", "SAT"]],
-  "abort": [["??"], ["TIME"]],
-  "clear": [["??"], ["CLS"]],
-  "today": [["??"], ["TODAY"]],
-  "close": [["??"], ["CLOSE"]]
-}
-
-Calendar.prototype.draw = function () {
-  calendar = this;
-
-  var mvAry = [];
-  mvAry[mvAry.length] = ' <div name="calendarForm" style="margin: 0px;">';
-  mvAry[mvAry.length] = '    <table width="100%" border="0" cellpadding="0" cellspacing="1">';
-  mvAry[mvAry.length] = '      <tr>';
-  mvAry[mvAry.length] = '        <th align="left" width="1%"><input style="border: 1px solid '
-      + calendar.colors["input_border"]
-      + ';background-color:'
-      + calendar.colors["input_bg"]
-      + ';width:16px;height:20px;" name="prevMonth" type="button" id="prevMonth" value="<" /></th>';
-  mvAry[mvAry.length] = '        <th align="center" width="98%" nowrap="nowrap"><select name="calendarYear" id="calendarYear" style="font-size:12px;"></select><select name="calendarMonth" id="calendarMonth" style="font-size:12px;"></select></th>';
-  mvAry[mvAry.length] = '        <th align="right" width="1%"><input style="border: 1px solid '
-      + calendar.colors["input_border"]
-      + ';background-color:'
-      + calendar.colors["input_bg"]
-      + ';width:16px;height:20px;" name="nextMonth" type="button" id="nextMonth" value=">" /></th>';
-  mvAry[mvAry.length] = '      </tr>';
-  mvAry[mvAry.length] = '    </table>';
-  mvAry[mvAry.length] = '    <table id="calendarTable" width="100%" style="border:0px solid #CCCCCC;background-color:#FFFFFF" border="0" cellpadding="3" cellspacing="1">';
-  mvAry[mvAry.length] = '      <tr>';
-  for (var i = 0; i < 7; i++) {
-    mvAry[mvAry.length] = '      <th style="font-weight:normal;background-color:'
-        + calendar.colors["tr_bg"]
-        + ';color:'
-        + calendar.colors["tr_word"]
-        + ';">'
-        + Calendar.language["weeks"][this.lang][i] + '</th>';
-  }
-  mvAry[mvAry.length] = '      </tr>';
-  for (var i = 0; i < 6; i++) {
-    mvAry[mvAry.length] = '    <tr align="center">';
-    for (var j = 0; j < 7; j++) {
-      if (j == 0) {
-        mvAry[mvAry.length] = ' <td style="cursor:default;color:'
-            + calendar.colors["sun_word"] + ';"></td>';
-      } else if (j == 6) {
-        mvAry[mvAry.length] = ' <td style="cursor:default;color:'
-            + calendar.colors["sat_word"] + ';"></td>';
-      } else {
-        mvAry[mvAry.length] = ' <td style="cursor:default;"></td>';
-      }
-    }
-    mvAry[mvAry.length] = '    </tr>';
-  }
-
-  mvAry[mvAry.length] = '      <tr align="center" style="font-size:12px;">';
-  mvAry[mvAry.length] = '        <td name="abort" id="abort" colspan="1" style="cursor:default;">'
-      + Calendar.language["abort"][this.lang] + '</td>';
-  mvAry[mvAry.length] = '        <td colspan="6"><select name="calendarHour" id="calendarHour"></select>';
-  mvAry[mvAry.length] = ':<select name="calendarMinute" id="calendarMinute"></select>';
-  mvAry[mvAry.length] = ':<select name="calendarSecond" id="calendarSecond"></select>';
-  mvAry[mvAry.length] = '      </td></tr>';
-
-  mvAry[mvAry.length] = '      <tr style="background-color:'
-      + calendar.colors["input_bg"] + ';">';
-  mvAry[mvAry.length] = '        <th colspan="2"><input name="calendarClear" type="button" id="calendarClear" value="'
-      + Calendar.language["clear"][this.lang]
-      + '" style="border: 1px solid '
-      + calendar.colors["input_border"]
-      + ';background-color:'
-      + calendar.colors["input_bg"]
-      + ';width:100%;height:20px;font-size:12px;"/></th>';
-  mvAry[mvAry.length] = '        <th colspan="3"><input name="calendarToday" type="button" id="calendarToday" value="'
-      + Calendar.language["today"][this.lang]
-      + '" style="border: 1px solid '
-      + calendar.colors["input_border"]
-      + ';background-color:'
-      + calendar.colors["input_bg"]
-      + ';width:100%;height:20px;font-size:12px;"/></th>';
-  mvAry[mvAry.length] = '        <th colspan="2"><input name="calendarClose" type="button" id="calendarClose" value="'
-      + Calendar.language["close"][this.lang]
-      + '" style="border: 1px solid '
-      + calendar.colors["input_border"]
-      + ';background-color:'
-      + calendar.colors["input_bg"]
-      + ';width:100%;height:20px;font-size:12px;"/></th>';
-  mvAry[mvAry.length] = '      </tr>';
-  mvAry[mvAry.length] = '    </table>';
-  mvAry[mvAry.length] = ' </div>';
-  this.panel.innerHTML = mvAry.join("");
-
-  var obj = this.getElementById("prevMonth");
-  obj.onclick = function () {
-    calendar.goPrevMonth(calendar);
-  }
-  obj.onblur = function () {
-    calendar.onblur();
-  }
-  this.prevMonth = obj;
-
-  obj = this.getElementById("nextMonth");
-  obj.onclick = function () {
-    calendar.goNextMonth(calendar);
-  }
-  obj.onblur = function () {
-    calendar.onblur();
-  }
-  this.nextMonth = obj;
-
-  obj = this.getElementById("calendarClear");
-  obj.onclick = function () {
-    calendar.dateControl.value = "";
-    calendar.hide();
-  }
-  this.calendarClear = obj;
-
-  obj = this.getElementById("calendarClose");
-  obj.onclick = function () {
-    calendar.hide();
-  }
-  this.calendarClose = obj;
-
-  obj = this.getElementById("calendarYear");
-  obj.onchange = function () {
-    calendar.update(calendar);
-  }
-  obj.onblur = function () {
-    calendar.onblur();
-  }
-  this.calendarYear = obj;
-
-  obj = this.getElementById("calendarMonth");
-  with (obj) {
-    onchange = function () {
-      calendar.update(calendar);
-    }
-    onblur = function () {
-      calendar.onblur();
-    }
-  }
-  this.calendarMonth = obj;
-
-  obj = this.getElementById("calendarHour");
-  with (obj) {
-    length = 0;
-    for (var i = 0; i < 24; i++) {
-      if (i < 10) {
-        options[length] = new Option("0" + i, "0" + i);
-      } else {
-        options[length] = new Option(i, i);
-      }
-    }
-  }
-  this.calendarHour = obj;
-
-  obj = this.getElementById("calendarMinute");
-  with (obj) {
-    length = 0;
-    for (var i = 0; i < 60; i++) {
-      if (i < 10) {
-        options[length] = new Option("0" + i, "0" + i);
-      } else {
-        options[length] = new Option(i, i);
-      }
-    }
-  }
-  this.calendarMinute = obj;
-
-  obj = this.getElementById("calendarSecond");
-  with (obj) {
-    length = 0;
-    for (var i = 0; i < 60; i++) {
-      if (i < 10) {
-        options[length] = new Option("0" + i, "0" + i);
-      } else {
-        options[length] = new Option(i, i);
-      }
-    }
-  }
-  this.calendarSecond = obj;
-
-  obj = this.getElementById("calendarToday");
-  obj.onclick = function () {
-    var today = new Date();
-    calendar.date = today;
-    calendar.year = today.getFullYear();
-    calendar.month = today.getMonth();
-    calendar.changeSelect();
-    calendar.bindData();
-    calendar.dateControl.value = today.format(calendar.dateFormatStyle);
-    calendar.hide();
-  }
-  this.calendarToday = obj;
-}
-
-// ?????????
-Calendar.prototype.bindYear = function () {
-  var cy = this.calendarYear;
-  cy.length = 0;
-  for (var i = this.beginYear; i <= this.endYear; i++) {
-    cy.options[cy.length] = new Option(i
-        + Calendar.language["year"][this.lang], i);
-  }
-}
-
-// ?????????
-Calendar.prototype.bindMonth = function () {
-  var cm = this.calendarMonth;
-  cm.length = 0;
-  for (var i = 0; i < 12; i++) {
-    cm.options[cm.length] = new Option(
-        Calendar.language["months"][this.lang][i], i);
-  }
-}
-
-// ???????
-Calendar.prototype.getHour = function () {
-  return this.calendarHour.options[this.calendarHour.selectedIndex].value;
-}
-
-// ???????
-Calendar.prototype.getMinute = function () {
-  return this.calendarMinute.options[this.calendarMinute.selectedIndex].value;
-}
-
-// ??????
-Calendar.prototype.getSecond = function () {
-  return this.calendarSecond.options[this.calendarSecond.selectedIndex].value;
-}
-
-// ????
-Calendar.prototype.goPrevMonth = function (e) {
-  if (this.year == this.beginYear && this.month == 0) {
-    return;
-  }
-  this.month--;
-  if (this.month == -1) {
-    this.year--;
-    this.month = 11;
-  }
-  this.date = new Date(this.year, this.month, 1, this.getHour(), this
-  .getMinute(), this.getSecond());
-  this.changeSelect();
-  this.bindData();
-}
-
-// ????
-Calendar.prototype.goNextMonth = function (e) {
-  if (this.year == this.endYear && this.month == 11) {
-    return;
-  }
-  this.month++;
-  if (this.month == 12) {
-    this.year++;
-    this.month = 0;
-  }
-  this.date = new Date(this.year, this.month, 1, this.getHour(), this
-  .getMinute(), this.getSecond());
-  this.changeSelect();
-  this.bindData();
-}
-
-// ??SELECT????
-Calendar.prototype.changeSelect = function () {
-  var cy = this.calendarYear;
-  var cm = this.calendarMonth;
-  var ch = this.calendarHour;
-  var ci = this.calendarMinute;
-  var cs = this.calendarSecond;
-  for (var i = 0; i < cy.length; i++) {
-    if (cy.options[i].value == this.date.getFullYear()) {
-      cy[i].selected = true;
-      break;
-    }
-  }
-  for (var i = 0; i < cm.length; i++) {
-    if (cm.options[i].value == this.date.getMonth()) {
-      cm[i].selected = true;
-      break;
-    }
-  }
-  for (var i = 0; i < ch.length; i++) {
-    if (ch.options[i].value == this.date.getHours()) {
-      ch[i].selected = true;
-      break;
-    }
-  }
-  for (var i = 0; i < ci.length; i++) {
-    if (ci.options[i].value == this.date.getMinutes()) {
-      ci[i].selected = true;
-      break;
-    }
-  }
-  for (var i = 0; i < cs.length; i++) {
-    if (cs.options[i].value == this.date.getSeconds()) {
-      cs[i].selected = true;
-      break;
-    }
-  }
-}
-
-// ?????
-Calendar.prototype.update = function (e) {
-  this.year = e.calendarYear.options[e.calendarYear.selectedIndex].value;
-  this.month = e.calendarMonth.options[e.calendarMonth.selectedIndex].value;
-  this.date = new Date(this.year, this.month, 1, this.getHour(), this
-  .getMinute(), this.getSecond());
-  this.changeSelect();
-  this.bindData();
-}
-
-// ????????
-Calendar.prototype.bindData = function () {
-  var calendar = this;
-  var dateArray = this.getMonthViewArray(this.date.getFullYear(), this.date
-  .getMonth());
-  var tds = this.getElementById("calendarTable").getElementsByTagName("td");
-  for (var i = 0; i < tds.length; i++) {
-    tds[i].style.backgroundColor = calendar.colors["td_bg_out"];
-    tds[i].onclick = function () {
-      return;
-    }
-    tds[i].onmouseover = function () {
-      return;
-    }
-    tds[i].onmouseout = function () {
-      return;
-    }
-    if (i > dateArray.length - 1) {
-      break;
-    }
-    tds[i].innerHTML = dateArray[i];
-    if (dateArray[i] != " ") {
-      tds[i].onclick = function () {
-        if (calendar.dateControl != null) {
-          calendar.dateControl.value = new Date(calendar.date
-              .getFullYear(), calendar.date.getMonth(),
-              this.innerHTML, calendar.getHour(), calendar
-              .getMinute(), calendar.getSecond())
-          .format(calendar.dateFormatStyle);
-        }
-        calendar.hide();
-      }
-      tds[i].onmouseover = function () {
-        this.style.backgroundColor = calendar.colors["td_bg_over"];
-      }
-      tds[i].onmouseout = function () {
-        this.style.backgroundColor = calendar.colors["td_bg_out"];
-      }
-      if (new Date().format("yyyy-MM-dd") == new Date(calendar.date
-          .getFullYear(), calendar.date.getMonth(), dateArray[i])
-          .format("yyyy-MM-dd")) {
-        tds[i].style.backgroundColor = calendar.colors["cur_bg"];
-        tds[i].onmouseover = function () {
-          this.style.backgroundColor = calendar.colors["td_bg_over"];
-        }
-        tds[i].onmouseout = function () {
-          this.style.backgroundColor = calendar.colors["cur_bg"];
-        }
-      }// end if
-
-      // ???????????????
-      if (calendar.dateControl != null
-          && calendar.dateControl.value == new Date(calendar.date
-              .getFullYear(), calendar.date.getMonth(),
-              dateArray[i], calendar.getHour(), calendar
-              .getMinute(), calendar.getSecond())
-          .format(calendar.dateFormatStyle)) {
-        tds[i].style.backgroundColor = calendar.colors["sel_bg"];
-        tds[i].onmouseover = function () {
-          this.style.backgroundColor = calendar.colors["td_bg_over"];
-        }
-        tds[i].onmouseout = function () {
-          this.style.backgroundColor = calendar.colors["sel_bg"];
-        }
-      }
-    }
-  }
-}
-
-// ????????????(????)
-Calendar.prototype.getMonthViewArray = function (y, m) {
-  var mvArray = [];
-  var dayOfFirstDay = new Date(y, m, 1).getDay();
-  var daysOfMonth = new Date(y, m + 1, 0).getDate();
-  for (var i = 0; i < 42; i++) {
-    mvArray[i] = " ";
-  }
-  for (var i = 0; i < daysOfMonth; i++) {
-    mvArray[i + dayOfFirstDay] = i + 1;
-  }
-  return mvArray;
-}
-
-// ?? document.getElementById(id) ??????? from meizz tree source
-Calendar.prototype.getElementById = function (id) {
-  if (typeof (id) != "string" || id == "") {
-    return null;
-  }
-  if (document.getElementById) {
-    return document.getElementById(id);
-  }
-  if (document.all) {
-    return document.all(id);
-  }
-  try {
-    return eval(id);
-  } catch (e) {
-    return null;
-  }
-}
-
-// ?? object.getElementsByTagName(tagName)
-Calendar.prototype.getElementsByTagName = function (object, tagName) {
-  if (document.getElementsByTagName) {
-    return document.getElementsByTagName(tagName);
-  }
-  if (document.all) {
-    return document.all.tags(tagName);
-  }
-}
-
-// ??HTML??????
-Calendar.prototype.getAbsPoint = function (e) {
-  var x = e.offsetLeft;
-  var y = e.offsetTop;
-  while (e = e.offsetParent) {
-    x += e.offsetLeft;
-    y += e.offsetTop;
-  }
-  return {
-    "x": x,
-    "y": y
-  };
-}
-
-// ????
-Calendar.prototype.show = function (dateObj, popControl) {
-  if (dateObj == null) {
-    throw new Error("arguments[0] is necessary")
-  }
-  this.dateControl = dateObj;
-
-  this.date = (dateObj.value.length > 0) ? new Date(dateObj.value
-  .toDate(this.dateFormatStyle)) : new Date();// ??????????
-  this.year = this.date.getFullYear();
-  this.month = this.date.getMonth();
-  this.changeSelect();
-  this.bindData();
-  if (popControl == null) {
-    popControl = dateObj;
-  }
-  var xy = this.getAbsPoint(popControl);
-  this.panel.style.left = xy.x - 25 + "px";
-  this.panel.style.top = (xy.y + dateObj.offsetHeight) + "px";
-
-  this.panel.style.display = "";
-  this.container.style.display = "";
-
-  dateObj.onblur = function () {
-    calendar.onblur();
-  }
-  this.container.onmouseover = function () {
-    isFocus = true;
-  }
-  this.container.onmouseout = function () {
-    isFocus = false;
-  }
-}
-
-// ????
-Calendar.prototype.hide = function () {
-  this.panel.style.display = "none";
-  this.container.style.display = "none";
-  isFocus = false;
-}
-
-// ?????????
-Calendar.prototype.onblur = function () {
-  if (!isFocus) {
-    this.hide();
-  }
-}
-document
-.write(
-    '<div id="ContainerPanel" style="display:none;"><div id="calendarPanel" style="position: absolute;display: none;z-index: 9999;');
-document
-.write(
-    'background-color: #FFFFFF;border: 1px solid #CCCCCC;width:175px;font-size:12px;margin-left:25px;"></div>');
-/**if (document.all) {
-	document
-			.write('<iframe style="position:absolute;z-index:2000;width:expression(this.previousSibling.offsetWidth);');
-	document.write('height:expression(this.previousSibling.offsetHeight);');
-	document
-			.write('left:expression(this.previousSibling.offsetLeft);top:expression(this.previousSibling.offsetTop);');
-	document
-			.write('display:expression(this.previousSibling.style.display);" scrolling="no" frameborder="no"></iframe>');
-}*/
-document.write('</div>');
-
-
-
-
diff --git a/saga-web/src/main/resources/static/js/request.js b/saga-web/src/main/resources/static/js/request.js
deleted file mode 100644
index 6dcd1ab5..00000000
--- a/saga-web/src/main/resources/static/js/request.js
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- *  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.
- */
-
-window.content = {};
-$(function () {
-    window.content.requests = [];
-
-    $("#text-switch").bootstrapSwitch();
-    $('#parents').multiselect();
-
-    $("#text-switch").on('switchChange.bootstrapSwitch', function (event, state) {
-        if (state == true) {
-            $('#view-content').hide();
-            $('#text-content').show();
-        } else {
-            $('#text-content').hide();
-            $('#view-content').show();
-        }
-    });
-
-    $('#send-request').click(function () {
-        var content = $('#content').val();
-        $("#v_loading").show();
-        $.ajax({
-            type: "POST",
-            url: $("#submit-url").val(),
-            data: content,
-            contentType: "text/plain; charset=utf-8",
-            dataType: "json",
-            success: function (msg) {
-                $("#v_loading").hide();
-            },
-            error: function (req) {
-                alert(req.statusText);
-                $("#v_loading").hide();
-            }
-        });
-    });
-
-    $('#policyName').change(function() {
-        window.content.policy = $('#policyName option:selected').text();
-        $('#content').val(JSON.stringify(window.content, null, 2));
-    });
-
-    $("#addRequest").click(function() {
-        clearModalValues();
-        var requestIds = getRequestIds();
-        $("#requestModal").modal('show');
-        $("#parents").multiselect("dataprovider", requestIds);
-
-        $("#saveRequest").unbind("click").click(function(){
-            window.content.policy = $('#policyName option:selected').text();
-            var isUpdatedRequest = saveRequest();
-            if (!isUpdatedRequest) {
-                var value = $('#type option:selected').text();
-                var content = '<tr><td>' + $('#id').val() + '</td><td>' + value + '</td><td>' + $('#service-name').val() +
-                    '</td><td><button type="button" class="btn btn-primary requests-view-button" id=' + $('#id').val() +
-                    '>View</button></td><td><button class="btn btn-danger requests-remove-button" id=' + $('#id').val() +
-                    '>Remove</button></td></tr>';
-                $('#requests').append(content);
-                $('.requests-view-button').click(function(){
-                    var requestId = this.id;
-                    var request = {};
-                    window.content.requests.some(function(req) {
-                        if (req.id == requestId) {
-                            request = req;
-                            return true;
-                        }
-                        return false;
-                    });
-                    loadModalValues(request);
-                    $('#requestModal').modal('show');
-                });
-                $('.requests-remove-button').click(function(){
-                    var requestId = this.id;
-                    window.content.requests = window.content.requests.filter(function(item) {
-                        return item.id != requestId;
-                    });
-                    $('#content').val(JSON.stringify(window.content, null, 2));
-                    $(this).parent().parent().remove();
-                });
-            }
-            $('#requestModal').modal('hide');
-            $('#content').val(JSON.stringify(window.content, null, 2));
-        });
-    });
-
-    addParameter('transaction');
-    addParameter('compensation');
-
-    $('#reset').click(function() {
-        $('#content').val('');
-        window.content = {};
-        window.content.requests = [];
-        $('#policyName').prop('selectedIndex', 0);
-        $('#requests tbody').empty();
-    });
-});
-
-function clearModalValues() {
-    $('#id').val('');
-    $('#type').prop('selectedIndex', 0);
-    $('#service-name').val('');
-    $('#transaction-method').prop('selectedIndex', 0);
-    $('#transaction-path').val('');
-    $('#transaction-params tr').remove();
-    $('#compensation-method').prop('selectedIndex', 0);
-    $('#compensation-path').val('');
-    $('#compensation-params tr').remove();
-    $('#parents').multiselect('deselectAll', true);
-    $('#transaction-params-json-div').hide();
-    $('#transaction-params-json').val('');
-    $('#compensation-params-json-div').hide();
-    $('#compensation-params-json').val('');
-}
-
-function loadParameterValue(operationName, operation, type) {
-    if (type in operation.params && operation.params[type].length != 0) {
-        var form = operation.params[type];
-        for (var key in form) {
-            var content = '<tr><td>' + type + '</td><td><input type="text" value="' + key +
-                '"></td><td><input type="text" value="' + form[key] +
-                '"></td><td><button class="btn btn-danger remove-button">Remove</button></td></tr>';
-            $('#' + operationName + '-params').append(content);
-            removeRowFromTable('.remove-button');
-        }
-    }
-}
-
-function loadParameterValues(operationName, operation) {
-    loadParameterValue(operationName, operation, 'form');
-    loadParameterValue(operationName, operation, 'query');
-    if ('json' in operation.params) {
-        $('#' + operationName + '-params-json').val(operation.params.json);
-        $('#' + operationName + '-params-json-div').show();
-    }
-}
-
-function loadOperationModalValue(operationName, operation) {
-    $('#' + operationName + '-method').val(operation.method);
-    $('#' + operationName + '-path').val(operation.path);
-    loadParameterValues(operationName, operation);
-}
-
-function loadModalValues(request) {
-    clearModalValues();
-    $('#id').val(request.id);
-    $('#type').val(request.type);
-    $('#service-name').val(request.serviceName);
-
-    loadOperationModalValue('transaction', request.transaction);
-    loadOperationModalValue('compensation', request.compensation);
-
-    var requestIds = getRequestIds();
-    requestIds = requestIds.filter(function(item) {
-        return item.value != request.id;
-    });
-    $("#parents").multiselect("dataprovider", requestIds);
-    if (request.parents != null && request.parents.length != 0) {
-        $('#parents').multiselect('select', request.parents);
-    }
-}
-
-function retrieveParameterValues(operationName) {
-    var parameters = {};
-    var query = {};
-    var form = {};
-
-    if ($('#' + operationName + '-params').children().length != 0) {
-        $('#' + operationName + '-params tr').each(function() {
-            var type = $(this).find("td:nth-child(1)").html();
-            var key = $(this).find("td:nth-child(2) input").val();
-            var value = $(this).find("td:nth-child(3) input").val();
-            if (type === 'query') {
-                query[key] = value;
-            } else {
-                form[key] = value;
-            }
-        });
-    }
-
-    if (!isDictEmpty(query)) {
-        parameters.query = query;
-    }
-
-    if (!isDictEmpty(form)) {
-        parameters.form = form;
-    }
-
-    var jsonParameter = $('#' + operationName + '-params-json').val();
-    if (jsonParameter != '') {
-        parameters.json = jsonParameter;
-    }
-    return parameters;
-}
-
-function retrieveOperationValues(operationName) {
-    var operation = {};
-    operation.method = $('#' + operationName + '-method option:selected').text();
-    operation.path = $('#' + operationName + '-path').val();
-    operation.params = retrieveParameterValues(operationName);
-    return operation;
-}
-
-function saveRequest() {
-    var request = {};
-    request.id = $('#id').val();
-    request.type = $('#type option:selected').text();
-    request.serviceName = $('#service-name').val();
-
-    var transaction = retrieveOperationValues('transaction');
-    if (!isDictEmpty(transaction)) {
-        request.transaction = transaction;
-    }
-
-    var compensation = retrieveOperationValues('compensation');
-    if (!isDictEmpty(compensation)) {
-        request.compensation = compensation;
-    }
-
-    var parents = [];
-    $("#parents option:selected").each(function() {
-        parents.push(this.text);
-    });
-    if (parents.length != 0) {
-        request.parents = parents;
-    }
-
-    var isRequestUpdated = false;
-    window.content.requests.some(function(obj, index, arr) {
-        if (obj.id == request.id) {
-            arr[index] = request;
-            isRequestUpdated = true;
-            return true;
-        }
-        return false;
-    });
-    if (!isRequestUpdated) {
-        window.content.requests.push(request);
-    }
-    return isRequestUpdated;
-}
-
-function getRequestIds() {
-    var requests = window.content.requests;
-    var requestIds = [];
-    requests.forEach(function(req) {
-        requestIds.push({"label": req.id, "value": req.id});
-    });
-    return requestIds;
-}
-
-function addParameterRowInTable(clickableSelector, tableSelector, type) {
-    $(clickableSelector).click(function() {
-        $(tableSelector).append('<tr><td>' + type + '</td><td><input></td><td><input></td><td><button class="btn btn-danger remove-button">Remove</button></td></tr>');
-        removeRowFromTable('.remove-button');
-    });
-}
-
-function addJsonParameter(clickableSelector, textAreaSelector) {
-    $(clickableSelector).click(function() {
-        $(textAreaSelector).show();
-    });
-}
-
-function addParameter(operationName) {
-    addParameterRowInTable('#' + operationName + '-new-query-btn', '#' + operationName + '-params', 'query');
-    addParameterRowInTable('#' + operationName + '-new-form-btn', '#' + operationName + '-params', 'form');
-    addJsonParameter('#' + operationName + '-new-json-btn', '#' + operationName + '-params-json-div');
-}
-
-function removeRowFromTable(buttonSelector) {
-    $(buttonSelector).click(function() {
-        $(this).parent().parent().remove();
-    });
-}
-
-function isDictEmpty(obj) {
-    return Object.keys(obj).length === 0;
-}
diff --git a/saga-web/src/main/resources/static/js/table.js b/saga-web/src/main/resources/static/js/table.js
deleted file mode 100644
index a0e6763c..00000000
--- a/saga-web/src/main/resources/static/js/table.js
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- *  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.
- */
-
-$("#content").bootstrapTable({
-  method: 'get',
-  dataType: 'json',
-  url: '/saga-service/requests/',
-  queryParams: function queryParams(params) {
-    var start = $('#startPicker').find("input").val();
-    var end = $('#endPicker').find("input").val();
-    return {
-      startTime: changeDateFormat(start),
-      endTime: changeDateFormat(end),
-      pageIndex: params.pageNumber,
-      pageSize: params.limit
-    };
-
-  }
-  ,
-  cache: false,
-  totalField: 'totalCount',
-  dataField: 'requests',
-  striped: true,
-  pageNumber: 0,
-  pageSize: 50,
-  pagination: true,
-  sidePagination: "server",
-  queryParamsType: 'limit',
-  columns: [
-    {checkbox: true},
-    {
-      field: 'id',
-      title: 'Id',
-      align: 'center',
-      width: '10%'
-    },
-    {
-      field: 'sagaId',
-      title: 'SagaId',
-      align: 'center',
-      width: '35%'
-    },
-    {
-      field: 'startTime',
-      title: 'StartTime',
-      align: 'center',
-      width: '20%',
-      //?????????????????
-      formatter: function (value, row, index) {
-        return changeDateFormat(value);
-      }
-    },
-    {
-      field: 'completedTime',
-      title: 'CompletedTime',
-      align: 'center',
-      width: '20%',
-      //?????????????????
-      formatter: function (value, row, index) {
-        return changeDateFormat(value);
-      }
-    },
-    {
-      field: 'status',
-      title: 'Status',
-      align: 'center',
-      width: '15%',
-      //??????
-      formatter: function (value, row, index) {
-        return statusDetails(value, row);
-      }
-    }
-
-  ]
-
-});
-
-function refresh(params) {
-
-  var start = $('#startPicker').find("input").val();
-  var end = $('#endPicker').find("input").val();
-
-  var params = {
-    startTime: changeDateFormat(start),
-    endTime: changeDateFormat(end),
-    pageIndex: 0,
-    pageSize: 50
-  }
-  $('#content').bootstrapTable('refresh', params);
-}
-
-//????
-function changeDateFormat(value) {
-  var date = new Date(value);
-  var y = date.getFullYear();
-  var m = date.getMonth() + 1;
-  m = m < 10 ? ('0' + m) : m;
-  var d = date.getDate();
-  d = d < 10 ? ('0' + d) : d;
-  var h = date.getHours();
-  var minute = date.getMinutes();
-  minute = minute < 10 ? ('0' + minute) : minute;
-  var second = date.getSeconds();
-  second = second < 10 ? ('0' + second) : second;
-  return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;
-}
-
-//??????
-function statusDetails(value, row) {
-  var sagaId = row.sagaId;
-  var url = "<a href='detail.html?sagaId=" + sagaId + "'>" + value + "</a>";
-  return url;
-}
-
diff --git a/saga-web/src/main/resources/static/request.html b/saga-web/src/main/resources/static/request.html
deleted file mode 100644
index aed6f0a3..00000000
--- a/saga-web/src/main/resources/static/request.html
+++ /dev/null
@@ -1,232 +0,0 @@
-<!DOCTYPE HTML>
-<!--
-  ~ 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.
-  -->
-<html>
-<head>
-  <title>Request</title>
-  <link rel="stylesheet" href="css/style.css" type="text/css">
-  <link rel="stylesheet" href="css/request.css" type="text/css">
-  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
-  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-switch/3.3.4/css/bootstrap2/bootstrap-switch.min.css" type="text/css">
-  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-multiselect/0.9.13/css/bootstrap-multiselect.css" />
-
-  <script src="http://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
-  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
-  <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-switch/3.3.4/js/bootstrap-switch.min.js"></script>
-  <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-multiselect/0.9.13/js/bootstrap-multiselect.min.js"></script>
-  <script src="js/request.js"></script>
-</head>
-<body>
-<ul id="nav">
-  <li><a href="request.html">Request</a></li>
-  <li><a href="result.html">Result</a></li>
-  <li><a href="#">About</a></li>
-</ul>
-
-<div class="container-fluid">
-  <h3>Send a new Saga Request</h3>
-  <div class="row">
-    <div class="col-sm-8"></div>
-    <div class="row">
-      <div class="col-sm-2">
-        <h4>Text <input type="checkbox" id="text-switch"></h4>
-      </div>
-      <div class="col-sm-1">
-        <button id="reset" type="button" class="btn btn-secondary btn-lg">Reset</button>
-      </div>
-    </div>
-
-    <div id="view-content">
-      <form>
-        <div class="form-row col-lg-12">
-          <div class="form-group col-lg-12">
-            <div class="col-lg-1">
-              <label for="policyName">Policy</label>
-            </div>
-            <div class="col-lg-2">
-              <select id="policyName" class="form-control">
-                <option selected>BackwardRecovery</option>
-                <option>ForwardRecovery</option>
-              </select>
-            </div>
-          </div>
-          <div class="form-group col-lg-12">
-            <div class="col-lg-1">
-              <label for="policyName">Requests</label>
-            </div>
-            <div class="col-lg-2">
-              <button type="button" class="btn btn-primary" id="addRequest">Add a new request</button>
-              <div class="modal fade" id="requestModal" tabindex="-1" role="dialog" aira-labelledby="requestModalLabel"
-                   aria-hidden="true">
-                <div class="modal-dialog" role="document">
-                  <div class="modal-content">
-                    <div class="modal-header">
-                      <h4 class="modal-title" id="requestModalLabel">New request</h4>
-                    </div>
-                    <div class="modal-body">
-                      <form>
-                        <div class="form-group row">
-                          <label for="id" class="col-sm-3 col-form-label">ID</label>
-                          <div class="col-sm-9">
-                            <input type="text" class="form-control" id="id">
-                          </div>
-                        </div>
-                        <div class="form-group row">
-                          <label for="type" class="col-sm-3 col-form-label">Type</label>
-                          <div class="col-sm-9">
-                            <select id="type" class="form-control">
-                              <option value="rest" selected>rest</option>
-                              <option value="NOP">NOP</option>
-                            </select>
-                          </div>
-                        </div>
-                        <div class="form-group row">
-                          <label for="service-name" class="col-sm-3 col-form-label">Service Name</label>
-                          <div class="col-sm-9">
-                            <input type="text" class="form-control" id="service-name">
-                          </div>
-                        </div>
-                        <h4>Transaction:</h4>
-                        <div class="form-group row">
-                          <label for="transaction-method" class="col-sm-3 col-form-label">Method</label>
-                          <div class="col-sm-9">
-                            <select id="transaction-method" class="form-control">
-                              <option value="put" selected>put</option>
-                              <option value="post">post</option>
-                              <option value="get">get</option>
-                              <option value="delete">delete</option>
-                            </select>
-                          </div>
-                        </div>
-                        <div class="form-group row">
-                          <label for="transaction-path" class="col-sm-3 col-form-label">Path</label>
-                          <div class="col-sm-9">
-                            <input type="text" class="form-control" id="transaction-path">
-                          </div>
-                        </div>
-                        <div class="form-group row">
-                          <label for="transaction-params-btn" class="col-sm-3 col-form-label">Params</label>
-                          <div class="col-sm-9">
-                            <button type="button" class="btn btn-primary" id="transaction-new-query-btn">Add query
-                              data
-                            </button>
-                            <button type="button" class="btn btn-primary" id="transaction-new-form-btn">Add form data
-                            </button>
-                            <button type="button" class="btn btn-primary" id="transaction-new-json-btn">Add json body
-                            </button>
-                          </div>
-                        </div>
-                        <table class="table" id="transaction-params">
-                        </table>
-                        <div class="form-group" id="transaction-params-json-div" hidden>
-                          <label for="transaction-params-json">json</label>
-                          <textarea class="form-control" rows="5" id="transaction-params-json"></textarea>
-                        </div>
-                        <h4>Compensation:</h4>
-                        <div class="form-group row">
-                          <label for="compensation-method" class="col-sm-3 col-form-label">Method</label>
-                          <div class="col-sm-9">
-                            <select id="compensation-method" class="form-control">
-                              <option value="post" selected>post</option>
-                              <option value="put">put</option>
-                              <option value="get">get</option>
-                              <option value="delete">delete</option>
-                            </select>
-                          </div>
-                        </div>
-                        <div class="form-group row">
-                          <label for="compensation-path" class="col-sm-3 col-form-label">Path</label>
-                          <div class="col-sm-9">
-                            <input type="text" class="form-control" id="compensation-path">
-                          </div>
-                        </div>
-                        <div class="form-group row">
-                          <label for="compensation-params-btn" class="col-sm-3 col-form-label">Params</label>
-                          <div class="col-sm-9">
-                            <button type="button" class="btn btn-primary" id="compensation-new-query-btn">Add query
-                              data
-                            </button>
-                            <button type="button" class="btn btn-primary" id="compensation-new-form-btn">Add form data
-                            </button>
-                            <button type="button" class="btn btn-primary" id="compensation-new-json-btn">Add json body
-                            </button>
-                          </div>
-                        </div>
-                        <table class="table" id="compensation-params">
-                        </table>
-                        <div class="form-group" id="compensation-params-json-div" hidden>
-                          <label for="compensation-params-json">json</label>
-                          <textarea class="form-control" rows="5" id="compensation-params-json"></textarea>
-                        </div>
-                        <div class="form-group row">
-                          <label for="parents-btn" class="h4 col-sm-3 col-form-label">Parents:</label>
-                          <div class="col-sm-9">
-                            <select id="parents" multiple="multiple">
-                            </select>
-                            <!-- <button type="button" class="btn btn-primary" id="parents-btn">Add a parent</button> -->
-                          </div>
-                        </div>
-                        <!-- <table class="table" id="parents"> -->
-                        <!-- </table> -->
-                    </div>
-                    <div class="modal-footer">
-                      <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
-                      <button type="button" class="btn btn-primary" id="saveRequest">Save</button>
-                    </div>
-      </form>
-    </div>
-  </div>
-</div>
-</div>
-</div>
-</div>
-<table class="table" id="requests">
-  <thead>
-  <th>Id</th>
-  <th>Type</th>
-  <th>Service Name</th>
-  <th>View</th>
-  <th>Remove</th>
-  </thead>
-</table>
-</div>
-</form>
-</div>
-
-<div id="text-content" hidden>
-  <textarea id="content" style="width:800px;height:600px;"></textarea>
-</div>
-
-<br>
-<div id="v_loading" class="loading" style="display:none;"><span></span></div>
-
-<form>
-  <div class="form-row col-lg-12">
-    <div class="form-row col-lg-4 col-md-8">
-      <div class="input-group">
-        <input id="submit-url" type="url" class="form-control" value="/saga-service/requests">
-        <span class="input-group-btn">
-                            <button class="btn btn-primary" type="button" id="send-request">Submit</button>
-                        </span>
-      </div>
-    </div>
-  </div>
-</form>
-</div>
-</div>
-</body>
-</html>
diff --git a/saga-web/src/main/resources/static/result.html b/saga-web/src/main/resources/static/result.html
deleted file mode 100644
index aceb9790..00000000
--- a/saga-web/src/main/resources/static/result.html
+++ /dev/null
@@ -1,67 +0,0 @@
-<!DOCTYPE HTML>
-<!--
-  ~ 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.
-  -->
-
-<html>
-<head>
-  <title>Result</title>
-  <link rel="stylesheet" href="css/style.css" type="text/css">
-  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
-  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.1/bootstrap-table.min.css" integrity="sha256-eU4xmpfQx1HSi5q1q2rHNcMEzTNJov7r2Wr/6zF3ANc=" crossorigin="anonymous" />
-  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.47/css/bootstrap-datetimepicker.min.css" integrity="sha256-yMjaV542P+q1RnH6XByCPDfUFhmOafWbeLPmqKh11zo=" crossorigin="anonymous" />
-
-  <script src="http://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
-  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
-  <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.1/bootstrap-table.min.js" integrity="sha256-eXHLyyVI+v6X1wbfg9NB05IWqOqY4E9185nHZgeDIhg=" crossorigin="anonymous"></script>
-  <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
-  <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.47/js/bootstrap-datetimepicker.min.js" integrity="sha256-5YmaxAwMjIpMrVlK84Y/+NjCpKnFYa8bWWBbUHSBGfU=" crossorigin="anonymous"></script>
-</head>
-<body>
-<ul id="nav">
-  <li><a href="request.html">Request</a></li>
-  <li><a href="result.html">Result</a></li>
-  <li><a href="#">About</a></li>
-</ul>
-
-<div id="search">
-  <div class="row">
-    <div class="col-sm-3">
-      <span>From: </span>
-      <input type='text' class="form-control" id='startPicker' />
-    </div>
-    <div class="col-sm-3">
-      <span>To: </span>
-      <input type='text' class="form-control" id='endPicker' />
-    </div>
-    <div class="col-sm-1">
-      <button onClick="refresh(this)">Search</button>
-    </div>
-  </div>
-</div>
-
-<div id="content"></div>
-<script type="text/javascript">
-  $(document).ready(function () {
-    $(function () {
-      $('#startPicker').datetimepicker();
-      $('#endPicker').datetimepicker();
-    });
-  });
-</script>
-<script src="js/table.js"></script>
-</body>
-</html>
diff --git a/transports/pom.xml b/transports/pom.xml
deleted file mode 100644
index d7878472..00000000
--- a/transports/pom.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?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</artifactId>
-    <groupId>org.apache.servicecomb.saga</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <groupId>org.apache.servicecomb.saga.transports</groupId>
-  <artifactId>transports</artifactId>
-  <name>Saga::Transports</name>
-
-  <packaging>pom</packaging>
-  <modules>
-    <module>transport-httpclient</module>
-    <module>transport-httpclient-spring</module>
-    <module>transport-resttemplate</module>
-  </modules>
-
-
-</project>
diff --git a/transports/transport-httpclient-spring/pom.xml b/transports/transport-httpclient-spring/pom.xml
deleted file mode 100644
index cec9a4b3..00000000
--- a/transports/transport-httpclient-spring/pom.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-<?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>transports</artifactId>
-    <groupId>org.apache.servicecomb.saga.transports</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>transport-httpclient-spring</artifactId>
-  <name>Saga::Transports::HttpClient Spring</name>
-
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot-dependencies</artifactId>
-        <version>${spring.boot.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.servicecomb.saga</groupId>
-      <artifactId>saga-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.servicecomb.saga.transports</groupId>
-      <artifactId>transport-httpclient</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter</artifactId>
-      <exclusions>
-        <exclusion>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-logging</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.github.tomakehurst</groupId>
-      <artifactId>wiremock-standalone</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.github.seanyinx</groupId>
-      <artifactId>unit-scaffolding</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-test</artifactId>
-    </dependency>
-  </dependencies>
-
-</project>
diff --git a/transports/transport-httpclient-spring/src/main/java/org/apache/servicecomb/saga/transports/HttpClientTransportConfig.java b/transports/transport-httpclient-spring/src/main/java/org/apache/servicecomb/saga/transports/HttpClientTransportConfig.java
deleted file mode 100644
index a10b5c62..00000000
--- a/transports/transport-httpclient-spring/src/main/java/org/apache/servicecomb/saga/transports/HttpClientTransportConfig.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.transports;
-
-import org.apache.servicecomb.saga.transports.httpclient.HttpClientTransport;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-public class HttpClientTransportConfig {
-
-  private final int requestTimeout;
-
-  public HttpClientTransportConfig(@Value("${saga.request.timeout:30000}") int requestTimeout) {
-    this.requestTimeout = requestTimeout;
-  }
-
-  @Bean
-  @ConditionalOnMissingBean(RestTransport.class)
-  RestTransport transport() {
-    return new HttpClientTransport(requestTimeout);
-  }
-}
diff --git a/transports/transport-httpclient-spring/src/main/resources/META-INF/spring.factories b/transports/transport-httpclient-spring/src/main/resources/META-INF/spring.factories
deleted file mode 100644
index 6265ce1f..00000000
--- a/transports/transport-httpclient-spring/src/main/resources/META-INF/spring.factories
+++ /dev/null
@@ -1,19 +0,0 @@
-## ---------------------------------------------------------------------------
-## 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.
-## ---------------------------------------------------------------------------
-
-org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-  org.apache.servicecomb.saga.transports.HttpClientTransportConfig
diff --git a/transports/transport-httpclient-spring/src/test/java/org/apache/servicecomb/saga/transports/RestTransportTest.java b/transports/transport-httpclient-spring/src/test/java/org/apache/servicecomb/saga/transports/RestTransportTest.java
deleted file mode 100644
index 2fa105d2..00000000
--- a/transports/transport-httpclient-spring/src/test/java/org/apache/servicecomb/saga/transports/RestTransportTest.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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.transports;
-
-import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
-import static com.github.tomakehurst.wiremock.client.WireMock.get;
-import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
-import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
-import static com.seanyinx.github.unit.scaffolding.AssertUtils.expectFailing;
-import static java.util.Collections.emptyMap;
-import static org.apache.http.HttpStatus.SC_OK;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-
-import java.net.SocketTimeoutException;
-
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import com.github.tomakehurst.wiremock.junit.WireMockRule;
-
-import org.apache.servicecomb.saga.core.TransportFailedException;
-
-@RunWith(SpringRunner.class)
-@ContextConfiguration(classes = RestTransportTest.Config.class)
-public class RestTransportTest {
-
-  @Autowired
-  RestTransport transport;
-
-  @ClassRule
-  public static final WireMockRule wireMockRule = new WireMockRule(wireMockConfig().dynamicPort());
-
-  private static final String normalResource = "/rest/normalResource";
-  private static final String slowResource = "/rest/slowResource";
-
-  private String address;
-
-  @BeforeClass
-  public static void init() throws Exception {
-    System.setProperty("saga.request.timeout", "1000");
-
-    stubFor(get(urlPathEqualTo(normalResource))
-        .willReturn(
-            aResponse()
-                .withStatus(SC_OK)));
-
-    stubFor(get(urlPathEqualTo(slowResource))
-        .willReturn(
-            aResponse()
-                .withStatus(SC_OK)
-                .withFixedDelay(2000)));
-  }
-
-  @AfterClass
-  public static void shutdown() throws Exception {
-    System.clearProperty("saga.request.timeout");
-  }
-
-  @Before
-  public void setUp() throws Exception {
-    address = "localhost" + ":" + wireMockRule.port();
-  }
-
-  @Test
-  public void ensureNormalRequestWorksFineWithRequestTimeout() throws Exception {
-    SagaResponse response = null;
-    try {
-      response = transport.with(address, normalResource, "GET", emptyMap());
-    } catch (Exception e) {
-      fail("unexpected exception throw: " + e);
-    }
-    assertThat(response.succeeded(), is(true));
-  }
-
-  @Test
-  public void ensureSlowRequestFailsWithRequestTimeout() throws Exception {
-    try {
-      transport.with(address, slowResource, "GET", emptyMap());
-      expectFailing(TransportFailedException.class);
-    } catch (TransportFailedException e) {
-      assertThat(SocketTimeoutException.class.isInstance(e.getCause()), is(true));
-    }
-  }
-
-  @Configuration
-  @ComponentScan
-  static class Config {
-    @Bean
-    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
-      return new PropertySourcesPlaceholderConfigurer();
-    }
-  }
-}
diff --git a/transports/transport-httpclient-spring/src/test/resources/log4j2.xml b/transports/transport-httpclient-spring/src/test/resources/log4j2.xml
deleted file mode 100644
index 58924c68..00000000
--- a/transports/transport-httpclient-spring/src/test/resources/log4j2.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?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>
-    <Root level="info">
-      <AppenderRef ref="Console"/>
-    </Root>
-  </Loggers>
-</Configuration>
diff --git a/transports/transport-httpclient/pom.xml b/transports/transport-httpclient/pom.xml
deleted file mode 100644
index 8cfd5b42..00000000
--- a/transports/transport-httpclient/pom.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?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>transports</artifactId>
-    <groupId>org.apache.servicecomb.saga.transports</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>transport-httpclient</artifactId>
-  <name>Saga::Transports::HttpClient</name>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.servicecomb.saga</groupId>
-      <artifactId>saga-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.httpcomponents</groupId>
-      <artifactId>fluent-hc</artifactId>
-      <version>4.5.3</version>
-    </dependency>
-    <dependency>
-      <groupId>io.kamon</groupId>
-      <artifactId>kamon-core_2.12</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.kamon</groupId>
-      <artifactId>kamon-annotation_2.12</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.github.tomakehurst</groupId>
-      <artifactId>wiremock-standalone</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.github.seanyinx</groupId>
-      <artifactId>unit-scaffolding</artifactId>
-    </dependency>
-  </dependencies>
-
-</project>
diff --git a/transports/transport-httpclient/src/main/java/org/apache/servicecomb/saga/transports/httpclient/HttpClientTransport.java b/transports/transport-httpclient/src/main/java/org/apache/servicecomb/saga/transports/httpclient/HttpClientTransport.java
deleted file mode 100644
index 0a9e1604..00000000
--- a/transports/transport-httpclient/src/main/java/org/apache/servicecomb/saga/transports/httpclient/HttpClientTransport.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.transports.httpclient;
-
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.function.Function;
-
-import org.apache.http.HttpResponse;
-import org.apache.http.client.fluent.Form;
-import org.apache.http.client.fluent.Request;
-import org.apache.http.client.utils.URIBuilder;
-import org.apache.http.entity.ContentType;
-import org.apache.logging.log4j.core.util.IOUtils;
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.apache.servicecomb.saga.core.SuccessfulSagaResponse;
-
-import org.apache.servicecomb.saga.core.TransportFailedException;
-import org.apache.servicecomb.saga.transports.RestTransport;
-import kamon.annotation.EnableKamon;
-import kamon.annotation.Segment;
-
-@EnableKamon
-public class HttpClientTransport implements RestTransport {
-
-  private final int requestTimeout;
-  private static final int DEFAULT_REQUEST_TIMEOUT = 30000;
-
-  private static final Map<String, Function<URI, Request>> requestFactories = new HashMap<String, Function<URI, Request>>() {{
-    put("GET", Request::Get);
-    put("POST", Request::Post);
-    put("PUT", Request::Put);
-    put("DELETE", Request::Delete);
-  }};
-
-  public HttpClientTransport() {
-    this(DEFAULT_REQUEST_TIMEOUT);
-  }
-
-  public HttpClientTransport(int requestTimeout) {
-    this.requestTimeout = requestTimeout;
-  }
-
-  @Segment(name = "transport", category = "network", library = "kamon")
-  @Override
-  public SagaResponse with(String address, String path, String method, Map<String, Map<String, String>> params) {
-    URIBuilder builder = new URIBuilder().setScheme("http").setHost(address).setPath(path);
-
-    if (params.containsKey("query")) {
-      for (Entry<String, String> entry : params.get("query").entrySet()) {
-        builder.addParameter(entry.getKey(), entry.getValue());
-      }
-    }
-
-    try {
-      URI uri = builder.build();
-      Request request = requestFactories.getOrDefault(
-          method.toUpperCase(),
-          exceptionThrowingFunction(method)).apply(uri);
-
-      request.socketTimeout(requestTimeout);
-      if (params.containsKey("json")) {
-        request.bodyString(params.get("json").get("body"), ContentType.APPLICATION_JSON);
-      }
-
-      if (params.containsKey("form")) {
-        Form form = Form.form();
-        for (Entry<String, String> entry : params.get("form").entrySet()) {
-          form.add(entry.getKey(), entry.getValue()).build();
-        }
-        request.bodyForm(form.build());
-      }
-
-      return this.on(request);
-    } catch (URISyntaxException e) {
-      throw new TransportFailedException("Wrong request URI", e);
-    }
-  }
-
-  private Function<URI, Request> exceptionThrowingFunction(String method) {
-    return u -> {
-      throw new TransportFailedException("No such method " + method);
-    };
-  }
-
-  private SagaResponse on(Request request) {
-    try {
-      HttpResponse httpResponse = request.execute().returnResponse();
-      int statusCode = httpResponse.getStatusLine().getStatusCode();
-      String content = IOUtils.toString(new InputStreamReader(httpResponse.getEntity().getContent()));
-      if (statusCode >= 200 && statusCode < 300) {
-        return new SuccessfulSagaResponse(content);
-      }
-      throw new TransportFailedException("The remote service returned with status code " + statusCode
-          + ", reason " + httpResponse.getStatusLine().getReasonPhrase()
-          + ", and content " + content);
-    } catch (IOException e) {
-      throw new TransportFailedException("Network Error", e);
-    }
-  }
-}
diff --git a/transports/transport-httpclient/src/test/java/org/apache/servicecomb/saga/transports/httpclient/HttpClientTransportTest.java b/transports/transport-httpclient/src/test/java/org/apache/servicecomb/saga/transports/httpclient/HttpClientTransportTest.java
deleted file mode 100644
index 1c32d3eb..00000000
--- a/transports/transport-httpclient/src/test/java/org/apache/servicecomb/saga/transports/httpclient/HttpClientTransportTest.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * 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.transports.httpclient;
-
-import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
-import static com.github.tomakehurst.wiremock.client.WireMock.containing;
-import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
-import static com.github.tomakehurst.wiremock.client.WireMock.get;
-import static com.github.tomakehurst.wiremock.client.WireMock.post;
-import static com.github.tomakehurst.wiremock.client.WireMock.put;
-import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
-import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
-import static com.seanyinx.github.unit.scaffolding.AssertUtils.expectFailing;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonMap;
-import static org.apache.http.HttpStatus.SC_INTERNAL_SERVER_ERROR;
-import static org.apache.http.HttpStatus.SC_OK;
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-
-import java.net.SocketTimeoutException;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-import com.github.tomakehurst.wiremock.junit.WireMockRule;
-
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.apache.servicecomb.saga.core.TransportFailedException;
-import org.apache.servicecomb.saga.transports.RestTransport;
-
-public class HttpClientTransportTest {
-
-  @ClassRule
-  public static final WireMockRule wireMockRule = new WireMockRule(wireMockConfig().dynamicPort());
-
-  private static final String usableResource = "/rest/usableResource";
-  private static final String faultyResource = "/rest/faultyResource";
-  private static final String slowResource = "/rest/slowResource";
-  private static final String usableResponse = "hello world";
-  private static final String faultyResponse = "no such resource";
-  private static final String json = "{\"hello\", \"world\"}";
-
-  private String address;
-
-  private final RestTransport transport = new HttpClientTransport();
-
-  @BeforeClass
-  public static void setUpClass() throws Exception {
-    stubFor(get(urlPathEqualTo(usableResource))
-        .withQueryParam("foo", equalTo("bar"))
-        .withQueryParam("hello", equalTo("world"))
-        .willReturn(
-            aResponse()
-                .withStatus(SC_OK)
-                .withBody(usableResponse)));
-
-    stubFor(post(urlPathEqualTo(faultyResource))
-        .withQueryParam("foo", equalTo("bar"))
-        .withRequestBody(containing("hello=world&jesus=christ"))
-        .willReturn(
-            aResponse()
-                .withStatus(SC_INTERNAL_SERVER_ERROR)
-                .withBody(faultyResponse)));
-
-    stubFor(put(urlPathEqualTo(usableResource))
-        .withQueryParam("foo", equalTo("bar"))
-        .withRequestBody(equalTo(json))
-        .willReturn(
-            aResponse()
-                .withStatus(SC_OK)
-                .withBody(usableResponse)));
-
-    stubFor(get(urlPathEqualTo(slowResource))
-        .willReturn(
-            aResponse()
-                .withStatus(SC_OK)
-                .withFixedDelay(2000)));
-  }
-
-  @Before
-  public void setUp() throws Exception {
-    address = "localhost" + ":" + wireMockRule.port();
-  }
-
-  @Test
-  public void getsRequestFromRemote() {
-    Map<String, Map<String, String>> requests = singletonMap("query", map("foo", "bar", "hello", "world"));
-
-    SagaResponse response = transport.with(address, usableResource, "GET", requests);
-
-    assertThat(response.succeeded(), is(true));
-    assertThat(response.body(), containsString(usableResponse));
-  }
-
-  @Test
-  public void putsRequestToRemote() {
-    Map<String, Map<String, String>> requests = new HashMap<>();
-    requests.put("query", singletonMap("foo", "bar"));
-    requests.put("json", singletonMap("body", json));
-
-    SagaResponse response = transport.with(address, usableResource, "PUT", requests);
-
-    assertThat(response.succeeded(), is(true));
-    assertThat(response.body(), containsString(usableResponse));
-  }
-
-  @Test
-  public void blowsUpWhenRemoteResponseIsNot2XX() {
-    Map<String, Map<String, String>> requests = new HashMap<>();
-    requests.put("query", singletonMap("foo", "bar"));
-    requests.put("form", map("hello", "world", "jesus", "christ"));
-
-    try {
-      transport.with(address, faultyResource, "POST", requests);
-      expectFailing(TransportFailedException.class);
-    } catch (TransportFailedException e) {
-      assertThat(e.getMessage(), containsString("The remote service returned with status code 500"));
-    }
-  }
-
-  @Test
-  public void blowsUpWhenRemoteIsNotReachable() {
-    try {
-      transport.with("http://somewhere:9090", faultyResource, "DELETE", emptyMap());
-      expectFailing(TransportFailedException.class);
-    } catch (TransportFailedException e) {
-      assertThat(e.getMessage(), is("Network Error"));
-    }
-  }
-
-  @Test
-  public void blowsUpWhenMethodIsUnknown() {
-    try {
-      transport.with(address, usableResource, "Blah", emptyMap());
-      expectFailing(TransportFailedException.class);
-    } catch (TransportFailedException e) {
-      assertThat(e.getMessage(), is("No such method Blah"));
-    }
-  }
-
-  @Test
-  public void blowsUpWhenUriIsMalformed() {
-    try {
-      transport.with("\\", usableResource, "GET", emptyMap());
-      expectFailing(TransportFailedException.class);
-    } catch (TransportFailedException e) {
-      assertThat(e.getMessage(), is("Wrong request URI"));
-    }
-  }
-
-  @Test
-  public void blowsUpWhenRequestTimeout() {
-    HttpClientTransport transportWithShortTimeout = new HttpClientTransport(1000);
-    try {
-      transportWithShortTimeout.with(address, slowResource, "GET", emptyMap());
-      expectFailing(TransportFailedException.class);
-    } catch (TransportFailedException e) {
-      assertThat(SocketTimeoutException.class.isInstance(e.getCause()), is(true));
-    }
-  }
-
-  private Map<String, String> map(String... pairs) {
-    return new LinkedHashMap<String, String>(){{
-      for (int i = 0; i < pairs.length; i+=2) {
-        put(pairs[i], pairs[i + 1]);
-      }
-    }};
-  }
-}
diff --git a/transports/transport-httpclient/src/test/resources/log4j2.xml b/transports/transport-httpclient/src/test/resources/log4j2.xml
deleted file mode 100644
index 58924c68..00000000
--- a/transports/transport-httpclient/src/test/resources/log4j2.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?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>
-    <Root level="info">
-      <AppenderRef ref="Console"/>
-    </Root>
-  </Loggers>
-</Configuration>
diff --git a/transports/transport-resttemplate/pom.xml b/transports/transport-resttemplate/pom.xml
deleted file mode 100644
index 8e63146a..00000000
--- a/transports/transport-resttemplate/pom.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-<?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>transports</artifactId>
-    <groupId>org.apache.servicecomb.saga.transports</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>transport-resttemplate</artifactId>
-  <name>Saga::Transports::RestTemplate</name>
-
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot-dependencies</artifactId>
-        <version>${spring.boot.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.servicecomb.saga</groupId>
-      <artifactId>saga-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter</artifactId>
-      <exclusions>
-        <exclusion>
-          <groupId>org.springframework.boot</groupId>
-          <artifactId>spring-boot-starter-logging</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter-web</artifactId>
-      <exclusions>
-        <exclusion>
-          <groupId>org.springframework.boot</groupId>
-          <artifactId>spring-boot-starter-logging</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-  </dependencies>
-
-</project>
diff --git a/transports/transport-resttemplate/src/main/java/org/apache/servicecomb/saga/transports/resttemplate/RestTemplateTransport.java b/transports/transport-resttemplate/src/main/java/org/apache/servicecomb/saga/transports/resttemplate/RestTemplateTransport.java
deleted file mode 100644
index 86f7ec79..00000000
--- a/transports/transport-resttemplate/src/main/java/org/apache/servicecomb/saga/transports/resttemplate/RestTemplateTransport.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.transports.resttemplate;
-
-import static java.util.Collections.emptyMap;
-import static org.springframework.http.HttpMethod.DELETE;
-import static org.springframework.http.HttpMethod.GET;
-import static org.springframework.http.HttpMethod.POST;
-import static org.springframework.http.HttpMethod.PUT;
-import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED;
-import static org.springframework.http.MediaType.APPLICATION_JSON;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.BiFunction;
-
-import org.apache.servicecomb.saga.core.SagaRequest;
-import org.apache.servicecomb.saga.core.SagaResponse;
-import org.apache.servicecomb.saga.core.SuccessfulSagaResponse;
-import org.springframework.http.HttpEntity;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.ResponseEntity;
-import org.springframework.http.client.ClientHttpResponse;
-import org.springframework.web.client.ResponseErrorHandler;
-import org.springframework.web.client.RestTemplate;
-import org.springframework.web.util.UriComponentsBuilder;
-
-import org.apache.servicecomb.saga.core.TransportFailedException;
-import org.apache.servicecomb.saga.transports.RestTransport;
-
-public class RestTemplateTransport implements RestTransport {
-
-  private final String protocol;
-  private final RestTemplate restTemplate;
-  private final Map<String, BiFunction<String, Map<String, Map<String, String>>, ResponseEntity<String>>> methodMapping = new HashMap<>();
-
-  public RestTemplateTransport(RestTemplate restTemplate, String protocol) {
-    this.protocol = protocol;
-    this.restTemplate = restTemplate;
-    this.restTemplate.setErrorHandler(new ResponseErrorHandler() {
-      @Override
-      public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException {
-        return false;
-      }
-
-      @Override
-      public void handleError(ClientHttpResponse clientHttpResponse) throws IOException {
-      }
-    });
-
-    methodMapping.put(GET.name(), exchange(GET));
-    methodMapping.put(PUT.name(), exchange(PUT));
-    methodMapping.put(POST.name(), exchange(POST));
-    methodMapping.put(DELETE.name(), exchange(DELETE));
-  }
-
-  @Override
-  public SagaResponse with(String address, String path, String method, Map<String, Map<String, String>> params) {
-    String url = buildUrl(address, path, params);
-
-    try {
-      ResponseEntity<String> responseEntity = methodHandler(method).apply(url, params);
-      return new SuccessfulSagaResponse(responseEntity.getBody());
-    } catch (Throwable e) {
-      throw new TransportFailedException(
-          String.format("The remote service %s failed to serve the %s request to %s ", address, method, path),
-          e);
-    }
-  }
-
-  private String buildUrl(String address, String path, Map<String, Map<String, String>> params) {
-    UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath(path);
-    params.getOrDefault(SagaRequest.PARAM_QUERY, emptyMap())
-        .forEach(uriComponentsBuilder::queryParam);
-
-    return protocol + address + uriComponentsBuilder.build().toString();
-  }
-
-  private BiFunction<String, Map<String, Map<String, String>>, ResponseEntity<String>> methodHandler(String method) {
-    return methodMapping.getOrDefault(method.toUpperCase(), (url, params) -> {
-      throw new TransportFailedException("No such method " + method);
-    });
-  }
-
-  private BiFunction<String, Map<String, Map<String, String>>, ResponseEntity<String>> exchange(HttpMethod method) {
-    return (url, params) -> restTemplate.exchange(url, method, request(params), String.class);
-  }
-
-  private HttpEntity<Object> request(Map<String, Map<String, String>> params) {
-    HttpHeaders headers = new HttpHeaders();
-
-    if (params.containsKey(SagaRequest.PARAM_JSON)) {
-      headers.setContentType(APPLICATION_JSON);
-      return new HttpEntity<>(params.get(SagaRequest.PARAM_JSON).get(SagaRequest.PARAM_JSON_BODY), headers);
-    }
-
-    if (params.containsKey(SagaRequest.PARAM_FORM)) {
-      headers.setContentType(APPLICATION_FORM_URLENCODED);
-      return new HttpEntity<>(params.get(SagaRequest.PARAM_FORM), headers);
-    }
-
-    return null;
-  }
-}


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

Mime
View raw message