You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ni...@apache.org on 2018/03/04 12:04:48 UTC

[incubator-servicecomb-saga] 01/02: SCB-363 Remove legacy code

This is an automated email from the ASF dual-hosted git repository.

ningjiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-saga.git

commit b8e39d16f6a650dce447b2dcae0fdd240b8de385
Author: Yang Bo <ya...@huawei.com>
AuthorDate: Fri Mar 2 01:09:12 2018 +0800

    SCB-363 Remove legacy code
    
    The support for legacy mode will be dropped, remove all the related
    code from master branch.
---
 docs/api/api.md                                    | 168 -----
 docs/old_saga.md                                   |  53 --
 integration-tests/coverage-aggregate/pom.xml       |  20 -
 pom.xml                                            |  50 +-
 saga-core/pom.xml                                  | 103 ---
 .../servicecomb/saga/core/BackwardRecovery.java    |  49 --
 .../apache/servicecomb/saga/core/Compensation.java |  33 -
 .../saga/core/CompensationTaskConsumer.java        |  69 --
 .../servicecomb/saga/core/CompositeSagaLog.java    |  40 --
 .../saga/core/CompositeSagaResponse.java           |  48 --
 .../apache/servicecomb/saga/core/Descriptive.java  |  25 -
 .../apache/servicecomb/saga/core/EventContext.java |  28 -
 .../servicecomb/saga/core/EventEnvelope.java       |  47 --
 .../apache/servicecomb/saga/core/EventStore.java   |  25 -
 .../servicecomb/saga/core/FailedSagaResponse.java  |  50 --
 .../org/apache/servicecomb/saga/core/Fallback.java |  25 -
 .../servicecomb/saga/core/FallbackPolicy.java      |  62 --
 .../servicecomb/saga/core/ForwardRecovery.java     |  53 --
 .../servicecomb/saga/core/GraphBasedSaga.java      | 132 ----
 .../apache/servicecomb/saga/core/IdGenerator.java  |  25 -
 .../saga/core/LoggingRecoveryPolicy.java           |  46 --
 .../servicecomb/saga/core/LongIdGenerator.java     |  30 -
 .../servicecomb/saga/core/NoOpSagaRequest.java     | 107 ----
 .../apache/servicecomb/saga/core/Operation.java    |  33 -
 .../servicecomb/saga/core/PersistentLog.java       |  22 -
 .../servicecomb/saga/core/PersistentStore.java     |  26 -
 .../servicecomb/saga/core/RecoveryPolicy.java      |  26 -
 .../servicecomb/saga/core/RequestProcessTask.java  |  67 --
 .../servicecomb/saga/core/RestOperation.java       |  59 --
 .../org/apache/servicecomb/saga/core/Saga.java     |  27 -
 .../apache/servicecomb/saga/core/SagaContext.java  |  36 --
 .../servicecomb/saga/core/SagaContextImpl.java     | 133 ----
 .../servicecomb/saga/core/SagaDefinition.java      |  25 -
 .../apache/servicecomb/saga/core/SagaEndTask.java  |  48 --
 .../servicecomb/saga/core/SagaEndedEvent.java      |  38 --
 .../apache/servicecomb/saga/core/SagaEvent.java    |  39 --
 .../servicecomb/saga/core/SagaException.java       |  29 -
 .../org/apache/servicecomb/saga/core/SagaLog.java  |  22 -
 .../apache/servicecomb/saga/core/SagaRequest.java  |  48 --
 .../servicecomb/saga/core/SagaRequestImpl.java     | 153 -----
 .../apache/servicecomb/saga/core/SagaResponse.java |  61 --
 .../saga/core/SagaStartFailedException.java        |  25 -
 .../servicecomb/saga/core/SagaStartTask.java       |  56 --
 .../servicecomb/saga/core/SagaStartedEvent.java    |  46 --
 .../apache/servicecomb/saga/core/SagaState.java    |  27 -
 .../org/apache/servicecomb/saga/core/SagaTask.java |  31 -
 .../servicecomb/saga/core/SagaTaskFactory.java     |  98 ---
 .../saga/core/SuccessfulSagaResponse.java          |  43 --
 .../apache/servicecomb/saga/core/TaskConsumer.java |  29 -
 .../apache/servicecomb/saga/core/TaskRunner.java   |  72 ---
 .../apache/servicecomb/saga/core/ToJsonFormat.java |  26 -
 .../apache/servicecomb/saga/core/Transaction.java  |  27 -
 .../saga/core/TransactionAbortedEvent.java         |  57 --
 .../saga/core/TransactionCompensatedEvent.java     |  56 --
 .../saga/core/TransactionEndedEvent.java           |  56 --
 .../saga/core/TransactionFailedException.java      |  29 -
 .../saga/core/TransactionStartedEvent.java         |  45 --
 .../saga/core/TransactionTaskConsumer.java         | 123 ----
 .../apache/servicecomb/saga/core/Transport.java    |  22 -
 .../saga/core/TransportFailedException.java        |  28 -
 .../saga/core/actors/ActorBasedSaga.java           |  65 --
 .../saga/core/actors/ActorBasedSagaFactory.java    |  83 ---
 .../saga/core/actors/CompletionCallbackActor.java  |  69 --
 .../saga/core/actors/EventContextImpl.java         |  60 --
 .../servicecomb/saga/core/actors/RequestActor.java | 206 ------
 .../saga/core/actors/RequestActorBuilder.java      | 108 ----
 .../saga/core/actors/RequestActorContext.java      |  82 ---
 .../saga/core/actors/messages/AbortMessage.java    |  37 --
 .../core/actors/messages/AbortRecoveryMessage.java |  33 -
 .../core/actors/messages/CompensateMessage.java    |  32 -
 .../messages/CompensationRecoveryMessage.java      |  22 -
 .../saga/core/actors/messages/FailMessage.java     |  33 -
 .../saga/core/actors/messages/Message.java         |  21 -
 .../saga/core/actors/messages/TransactMessage.java |  39 --
 .../messages/TransactionRecoveryMessage.java       |  32 -
 .../core/application/SagaExecutionComponent.java   |  87 ---
 .../saga/core/application/SagaFactory.java         |  30 -
 .../application/interpreter/FromJsonFormat.java    |  24 -
 .../interpreter/RestRequestChecker.java            |  55 --
 .../saga/core/dag/ByLevelTraveller.java            |  83 ---
 .../saga/core/dag/FromLeafTraversalDirection.java  |  38 --
 .../saga/core/dag/FromRootTraversalDirection.java  |  38 --
 .../saga/core/dag/GraphBasedSagaFactory.java       |  80 ---
 .../servicecomb/saga/core/dag/GraphBuilder.java    | 109 ----
 .../saga/core/dag/GraphCycleDetector.java          |  25 -
 .../saga/core/dag/GraphCycleDetectorImpl.java      |  70 ---
 .../org/apache/servicecomb/saga/core/dag/Node.java |  86 ---
 .../core/dag/SingleLeafDirectedAcyclicGraph.java   |  38 --
 .../servicecomb/saga/core/dag/Traveller.java       |  29 -
 .../saga/core/dag/TraversalDirection.java          |  29 -
 .../infrastructure/ContextAwareEventStore.java     |  56 --
 .../saga/infrastructure/EmbeddedEventStore.java    |  58 --
 .../servicecomb/saga/transports/RestTransport.java |  27 -
 .../saga/transports/TransportFactory.java          |  23 -
 .../saga/core/BackwardRecoveryTest.java            |  57 --
 .../servicecomb/saga/core/CompensationImpl.java    |  27 -
 .../saga/core/CompositeSagaLogTest.java            |  49 --
 .../saga/core/CompositeSagaResponseTest.java       |  73 ---
 .../apache/servicecomb/saga/core/DummyEvent.java   |  31 -
 .../servicecomb/saga/core/FallbackPolicyTest.java  |  91 ---
 .../servicecomb/saga/core/ForwardRecoveryTest.java |  59 --
 .../servicecomb/saga/core/LongIdGeneratorTest.java |  36 --
 .../servicecomb/saga/core/RestOperationTest.java   |  89 ---
 .../servicecomb/saga/core/RetrySagaLogTest.java    |  80 ---
 .../servicecomb/saga/core/SagaEndTaskTest.java     |  47 --
 .../servicecomb/saga/core/SagaEventMatcher.java    |  68 --
 .../saga/core/SagaExecutionComponentTestBase.java  | 250 --------
 .../servicecomb/saga/core/SagaIntegrationTest.java | 687 --------------------
 .../servicecomb/saga/core/SagaStartTaskTest.java   |  64 --
 .../servicecomb/saga/core/TransactionImpl.java     |  27 -
 .../ActorBasedSagaExecutionComponentTest.java      |  31 -
 .../core/actors/ActorBasedSagaIntegrationTest.java | 691 ---------------------
 .../core/actors/CompletionCallbackActorTest.java   | 138 ----
 .../saga/core/actors/EventContextImplTest.java     |  93 ---
 .../saga/core/actors/RequestActorBuilderTest.java  | 173 ------
 .../saga/core/actors/RequestActorTest.java         | 399 ------------
 .../dag/DirectedAcyclicGraphTraversalTest.java     | 102 ---
 .../dag/GraphBasedSagaExecutionComponentTest.java  |  33 -
 .../saga/core/dag/GraphBuilderTest.java            | 148 -----
 .../saga/core/dag/GraphCycleDetectorTest.java      |  73 ---
 .../apache/servicecomb/saga/core/dag/NodeTest.java |  80 ---
 .../infrastructure/ContextAwareEventStoreTest.java |  43 --
 saga-core/src/test/resources/application.conf      |  21 -
 saga-core/src/test/resources/log4j2.xml            |  30 -
 saga-demo/conditional-transaction-demo/README.md   | 174 ------
 .../conditional-transaction-demo-tests/pom.xml     | 301 ---------
 .../saga/demo/tests/ConditionalTransactionIT.java  | 155 -----
 .../docker-compose.yaml                            |  75 ---
 .../conditional-transaction-demo/inventory/pom.xml |  74 ---
 .../inventory/InventoryApplication.java            |  29 -
 .../transaction/inventory/InventoryController.java |  89 ---
 .../inventory/InventoryControllerTest.java         |  79 ---
 .../membership/pom.xml                             |  74 ---
 .../membership/MembershipApplication.java          |  29 -
 .../membership/MembershipController.java           |  62 --
 .../conditional-transaction-demo/payment/pom.xml   |  75 ---
 .../transaction/payment/PaymentApplication.java    |  29 -
 .../transaction/payment/PaymentController.java     |  84 ---
 .../transaction/payment/PaymentControllerTest.java |  61 --
 saga-demo/conditional-transaction-demo/pom.xml     |  40 --
 .../conditional-transaction-demo/supplier/pom.xml  |  74 ---
 .../transaction/supplier/SupplierApplication.java  |  29 -
 .../transaction/supplier/SupplierController.java   |  52 --
 .../src/main/resources/META-INF/LICENSE.txt        | 202 ------
 .../src/main/resources/META-INF/NOTICE.txt         |  11 -
 .../dependency-free-transaction-demo/README.md     | 168 -----
 .../car-rental-service/pom.xml                     |  85 ---
 .../saga/demo/car/rental/CarRentalApplication.java |  32 -
 .../saga/demo/car/rental/CarRentalController.java  | 100 ---
 .../src/main/resources/microservice.yaml           |  30 -
 .../demo-tests/pom.xml                             | 333 ----------
 .../apache/servicecomb/saga/demo/tests/DemoIT.java | 150 -----
 .../docker-compose.yaml                            | 101 ---
 .../flight-booking-service/pom.xml                 |  85 ---
 .../flight/booking/FlightBookingApplication.java   |  32 -
 .../flight/booking/FlightBookingController.java    |  77 ---
 .../src/main/resources/microservice.yaml           |  30 -
 .../hotel-reservation-service/pom.xml              |  85 ---
 .../reservation/HotelReservationApplication.java   |  32 -
 .../reservation/HotelReservationController.java    |  78 ---
 .../src/main/resources/microservice.yaml           |  30 -
 .../payment-service/pom.xml                        |  85 ---
 .../saga/demo/payment/PaymentApplication.java      |  32 -
 .../saga/demo/payment/PaymentController.java       |  81 ---
 .../src/main/resources/microservice.yaml           |  32 -
 saga-demo/dependency-free-transaction-demo/pom.xml |  67 --
 saga-demo/pom.xml                                  |   2 -
 saga-discovery/pom.xml                             |  37 --
 .../saga-discovery-servicecenter/pom.xml           | 124 ----
 .../center/ServiceCenterDiscoveryConfig.java       |  43 --
 .../src/main/resources/META-INF/spring.factories   |  18 -
 .../src/main/resources/microservice.yaml           |  30 -
 .../discovery/service/center/DummyController.java  |  56 --
 .../center/ServiceCenterDiscoveryApplication.java  |  32 -
 .../ServiceCenterDiscoveryRestTransportTest.java   | 132 ----
 .../src/test/resources/log4j2-test.xml             |  30 -
 .../src/test/resources/registry.yaml               |  23 -
 saga-format/pom.xml                                |  74 ---
 .../saga/core/FailedSagaRequestContext.java        |  40 --
 .../servicecomb/saga/core/JacksonToJsonFormat.java |  65 --
 .../servicecomb/saga/core/SagaRequestContext.java  |  37 --
 .../saga/core/SuccessfulSagaRequestContext.java    |  41 --
 .../servicecomb/saga/format/ChildrenExtractor.java |  55 --
 .../servicecomb/saga/format/JacksonFallback.java   |  64 --
 .../saga/format/JacksonFromJsonFormat.java         |  58 --
 .../saga/format/JacksonRestCompensation.java       |  52 --
 .../saga/format/JacksonRestFallback.java           |  43 --
 .../saga/format/JacksonRestOperation.java          |  62 --
 .../saga/format/JacksonRestTransaction.java        |  36 --
 .../saga/format/JacksonSagaEventFormat.java        | 114 ----
 .../saga/format/JsonFailedSagaResponse.java        |  29 -
 .../saga/format/JsonRestSagaRequest.java           |  72 ---
 .../saga/format/JsonSagaDefinition.java            |  60 --
 .../servicecomb/saga/format/JsonSagaRequest.java   |  39 --
 .../saga/format/JsonSuccessfulSagaResponse.java    |  30 -
 .../servicecomb/saga/format/SagaEventFormat.java   |  25 -
 .../servicecomb/saga/format/TransportAware.java    |  26 -
 .../saga/format/ChildrenExtractorTest.java         |  75 ---
 .../saga/format/JacksonFromJsonFormatTest.java     | 261 --------
 .../saga/format/JacksonRestOperationTest.java      |  69 --
 .../saga/format/JsonRestSagaRequestTest.java       |  95 ---
 .../saga/format/JsonSagaDefinitionTest.java        |  34 -
 .../saga/format/SagaEventFormatTest.java           | 180 ------
 saga-performance/README.md                         |  47 --
 saga-performance/images/grafana.png                | Bin 15508 -> 0 bytes
 saga-performance/scripts/saga.jmx                  | 289 ---------
 saga-persistence/pom.xml                           |  36 --
 saga-persistence/saga-persistence-jpa/pom.xml      |  89 ---
 .../jpa/EclipseLinkJpaConfiguration.java           |  50 --
 .../src/main/resources/META-INF/spring.factories   |  18 -
 saga-spring/pom.xml                                | 233 -------
 .../saga/spring/JpaPersistentStore.java            |  69 --
 .../servicecomb/saga/spring/SagaController.java    | 222 -------
 .../servicecomb/saga/spring/SagaEventEntity.java   |  85 ---
 .../servicecomb/saga/spring/SagaEventRepo.java     |  44 --
 .../saga/spring/SagaExecutionQueryService.java     | 160 -----
 .../saga/spring/SagaRecoveryListener.java          |  37 --
 .../saga/spring/SagaShutdownListener.java          |  42 --
 .../saga/spring/SagaSpringApplication.java         |  39 --
 .../servicecomb/saga/spring/SagaSpringConfig.java  | 136 ----
 saga-spring/src/main/resources/META-INF/aop.xml    |  25 -
 .../src/main/resources/META-INF/spring.factories   |  20 -
 saga-spring/src/main/resources/application.conf    |  88 ---
 saga-spring/src/main/resources/application.yaml    |  30 -
 saga-spring/src/main/resources/log4j2.xml          |  30 -
 .../src/main/resources/schema-postgresql.sql       |  26 -
 .../ActorBasedSagaSpringApplicationTest.java       |  25 -
 .../GraphBasedSagaSpringApplicationTest.java       |  25 -
 .../saga/spring/GreetingController.java            |  42 --
 .../servicecomb/saga/spring/SagaRecoveryTest.java  | 181 ------
 .../saga/spring/SagaServiceDiscoveryTest.java      | 113 ----
 .../saga/spring/SagaSpringApplicationTestBase.java | 390 ------------
 saga-spring/src/test/resources/data.sql            |  29 -
 saga-spring/src/test/resources/log4j2-test.xml     |  30 -
 saga-spring/src/test/resources/registry.yaml       |  23 -
 saga-web/pom.xml                                   | 130 ----
 .../servicecomb/saga/web/SagaWebApplication.java   |  34 -
 saga-web/src/main/resources/application.yaml       |  29 -
 saga-web/src/main/resources/microservice.yaml      |  31 -
 saga-web/src/main/resources/static/css/request.css |  66 --
 saga-web/src/main/resources/static/css/style.css   |  41 --
 saga-web/src/main/resources/static/detail.html     | 174 ------
 saga-web/src/main/resources/static/index.html      |  31 -
 saga-web/src/main/resources/static/js/date.js      | 660 --------------------
 saga-web/src/main/resources/static/js/request.js   | 294 ---------
 saga-web/src/main/resources/static/js/table.js     | 128 ----
 saga-web/src/main/resources/static/request.html    | 232 -------
 saga-web/src/main/resources/static/result.html     |  67 --
 transports/pom.xml                                 |  39 --
 transports/transport-httpclient-spring/pom.xml     |  80 ---
 .../saga/transports/HttpClientTransportConfig.java |  40 --
 .../src/main/resources/META-INF/spring.factories   |  19 -
 .../saga/transports/RestTransportTest.java         | 123 ----
 .../src/test/resources/log4j2.xml                  |  30 -
 transports/transport-httpclient/pom.xml            |  63 --
 .../transports/httpclient/HttpClientTransport.java | 121 ----
 .../httpclient/HttpClientTransportTest.java        | 192 ------
 .../src/test/resources/log4j2.xml                  |  30 -
 transports/transport-resttemplate/pom.xml          |  71 ---
 .../resttemplate/RestTemplateTransport.java        | 121 ----
 260 files changed, 4 insertions(+), 20094 deletions(-)

diff --git a/docs/api/api.md b/docs/api/api.md
deleted file mode 100755
index e0a9e8f..0000000
--- 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 [...]
-        },
-        {
-            "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\\\" [...]
-        },
-        {
-            "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  \\\"stat [...]
-        },
-        {
-            "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 [...]
-        },
-        {
-            "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}}, \"r [...]
-        },
-        {
-            "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 2b79d22..0000000
--- 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 a156600..cbb67ad 100644
--- a/integration-tests/coverage-aggregate/pom.xml
+++ b/integration-tests/coverage-aggregate/pom.xml
@@ -31,26 +31,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>
     </dependency>
     <dependency>
diff --git a/pom.xml b/pom.xml
index 85e9405..9207e14 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>
@@ -123,41 +116,6 @@
     <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>
         <version>0.0.3-SNAPSHOT</version>
       </dependency>
@@ -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 f9ba426..0000000
--- 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 e46de2f..0000000
--- 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 f642011..0000000
--- 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 736c34d..0000000
--- 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 017129a..0000000
--- 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 02ab48c..0000000
--- 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 bd367af..0000000
--- 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 79b0c3e..0000000
--- 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 9283b33..0000000
--- 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 7b7e6e2..0000000
--- 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 15d1701..0000000
--- 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 fca68a0..0000000
--- 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 48ad67d..0000000
--- 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 c783990..0000000
--- 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 f4544e3..0000000
--- 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 2add260..0000000
--- 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 9173eca..0000000
--- 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 6b16075..0000000
--- 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 56ad05e..0000000
--- 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 13b6f8a..0000000
--- 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 26ec4bc..0000000
--- 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 a7620b3..0000000
--- 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 c67d640..0000000
--- 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 e19c7bf..0000000
--- 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 5cce22d..0000000
--- 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 44f62ea..0000000
--- 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 309be44..0000000
--- 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 610ae27..0000000
--- 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 406c8df..0000000
--- 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 69daba7..0000000
--- 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 c6f4f9f..0000000
--- 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 ceb0ebe..0000000
--- 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 49ce989..0000000
--- 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 2e07b9f..0000000
--- 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 337abdd..0000000
--- 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 cbb7a23..0000000
--- 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 ecdfe4a..0000000
--- 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 0de35da..0000000
--- 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 d8a6bd1..0000000
--- 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 0d82fee..0000000
--- 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 eae3678..0000000
--- 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 73efcc0..0000000
--- 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 0fd2450..0000000
--- 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 d69bdcd..0000000
--- 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 5ae7494..0000000
--- 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 c078001..0000000
--- 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 cd6c449..0000000
--- 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 fafb845..0000000
--- 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 b117c94..0000000
--- 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 d6ab298..0000000
--- 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 603c542..0000000
--- 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 b55e01a..0000000
--- 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 cc35589..0000000
--- 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 af2dc74..0000000
--- 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 5679e0a..0000000
--- 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 e01a9d5..0000000
--- 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 bf60f98..0000000
--- 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 8ce22fa..0000000
--- 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 7cee4d3..0000000
--- 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 21a2928..0000000
--- 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 055174e..0000000
--- 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 5004b4e..0000000
--- 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 2e3149d..0000000
--- 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 f23a079..0000000
--- 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 951157d..0000000
--- 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 5fd0701..0000000
--- 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 421a092..0000000
--- 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 7a80ecb..0000000
--- 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 3ed8187..0000000
--- 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 e4c57a2..0000000
--- 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 26ba05b..0000000
--- 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 7a600d7..0000000
--- 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 b60b5e7..0000000
--- 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 ccfb408..0000000
--- 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 7a65e48..0000000
--- 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 22bc874..0000000
--- 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 d97c40f..0000000
--- 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 8c664ac..0000000
--- 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 2048383..0000000
--- 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 578cbb9..0000000
--- 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 9b12bc8..0000000
--- 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 6011a98..0000000
--- 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 0b3be0a..0000000
--- 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 cf0d19b..0000000
--- 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 e44848b..0000000
--- 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 22f7343..0000000
--- 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 40fa71d..0000000
--- 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 d342264..0000000
--- 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 3d5bda3..0000000
--- 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 b34b5bd..0000000
--- 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 4f03992..0000000
--- 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 c974bc4..0000000
--- 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 c7dea51..0000000
--- 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 be4b9f4..0000000
--- 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 c775afe..0000000
--- 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 a2d1f32..0000000
--- 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 e765170..0000000
--- 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 775866b..0000000
--- 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 7f1990d..0000000
--- 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 6da8f16..0000000
--- 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 22f5fa1..0000000
--- 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 7e8289c..0000000
--- 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 b9e893f..0000000
--- 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 d005ee7..0000000
--- 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 b1d0c4e..0000000
--- 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 a59b142..0000000
--- 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 01f8adb..0000000
--- 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 ac649f0..0000000
--- 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 5823a06..0000000
--- 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 cfd3788..0000000
--- 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 b3a2c14..0000000
--- 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 776b5aa..0000000
--- 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 beb9607..0000000
--- 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 8515f93..0000000
--- 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 8703c7a..0000000
--- 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 934c54b..0000000
--- 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 2da4ba0..0000000
--- 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 1216e5f..0000000
--- 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 0629dd6..0000000
--- 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 cae04cb..0000000
--- 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/conditional-transaction-demo/README.md b/saga-demo/conditional-transaction-demo/README.md
deleted file mode 100755
index 9ae1deb..0000000
--- 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
... 11964 lines suppressed ...

-- 
To stop receiving notification emails like this one, please contact
ningjiang@apache.org.