You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by se...@apache.org on 2017/12/26 10:41:18 UTC

[incubator-servicecomb-saga] branch SCB-97_alpha_omega_bonding created (now 9bd3b66)

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

seanyinx pushed a change to branch SCB-97_alpha_omega_bonding
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-saga.git.


      at 9bd3b66  SCB-97 glued request interception with transaction aop

This branch includes the following new commits:

     new 5f83a68  SCB-96 added request interceptor
     new 1aa8564  SCB-96 retrieve ids in header and put it into omega context
     new 02d8aa0  SCB-97 alpha is able to persist received events
     new a02a62c  SCB-97 removed unnecessary dependency on serializer
     new 2342a28  SCB-97 made alpha server port configurable with default 8080
     new 84b7f04  SCB-97 glued omega & alpha together
     new 9bd3b66  SCB-97 glued request interception with transaction aop

The 7 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


-- 
To stop receiving notification emails like this one, please contact
['"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>'].

[incubator-servicecomb-saga] 06/07: SCB-97 glued omega & alpha together

Posted by se...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

seanyinx pushed a commit to branch SCB-97_alpha_omega_bonding
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-saga.git

commit 84b7f040bc7576f089253440a5aab174728219ca
Author: seanyinx <se...@huawei.com>
AuthorDate: Tue Dec 26 17:06:23 2017 +0800

    SCB-97 glued omega & alpha together
    
    Signed-off-by: seanyinx <se...@huawei.com>
---
 .../io/servicecomb/saga/alpha/core/TxEvent.java    |  12 +-
 alpha/alpha-server/pom.xml                         |  32 +++++
 .../alpha/server/SwiftTxEventEndpointImpl.java     |   4 +-
 .../saga/alpha/server/TxEventEnvelope.java         |   4 +-
 .../src/main/resources/application.yaml            |  31 +++++
 .../alpha-server/src/main/resources/log4j2.xml     |  40 ++----
 .../src/main/resources/schema-mysql.sql            |  11 ++
 integration-tests/coverage-aggregate/pom.xml       |   8 ++
 .../pack-tests}/pom.xml                            | 140 ++++++---------------
 .../pack/tests/GreetingApplication.java            |  15 ++-
 .../integration/pack/tests/GreetingController.java |  52 ++++++++
 .../integration/pack/tests/GreetingService.java    |  18 ++-
 .../saga/integration/pack/tests/PackIT.java        |  52 ++++++++
 integration-tests/pom.xml                          |   1 +
 .../connector/thrift/ThriftMessageSender.java      |  21 +++-
 {integration-tests => omega/omega-format}/pom.xml  |  43 ++++---
 .../saga/omega/format/NativeMessageFormat.java     |  53 ++++++++
 .../saga/omega/format/NativeMessageFormatTest.java |  70 +++++++++++
 omega/{ => omega-spring-starter}/pom.xml           |  53 ++++----
 .../saga/omega/spring/EnableOmega.java}            |  17 ++-
 .../saga/omega/spring/OmegaSpringConfig.java       |  52 ++++++++
 .../spring/CompensableMethodCheckingCallback.java  |   3 +-
 .../spring/TransactionAspectConfig.java            |   2 +-
 .../spring/CompensableAnnotationCheckingTest.java  |   2 +-
 .../omega/transaction/MessageDeserializer.java     |   2 +-
 ...essageDeserializer.java => OmegaException.java} |   7 +-
 omega/pom.xml                                      |   2 +
 pom.xml                                            |  27 +++-
 .../conditional-transaction-demo-tests/pom.xml     |   2 +-
 .../demo-tests/pom.xml                             |   2 +-
 30 files changed, 571 insertions(+), 207 deletions(-)

diff --git a/alpha/alpha-core/src/main/java/io/servicecomb/saga/alpha/core/TxEvent.java b/alpha/alpha-core/src/main/java/io/servicecomb/saga/alpha/core/TxEvent.java
index abd8fbd..2d0a19b 100644
--- a/alpha/alpha-core/src/main/java/io/servicecomb/saga/alpha/core/TxEvent.java
+++ b/alpha/alpha-core/src/main/java/io/servicecomb/saga/alpha/core/TxEvent.java
@@ -17,8 +17,10 @@
 
 package io.servicecomb.saga.alpha.core;
 
+import java.util.Date;
+
 public class TxEvent {
-  private long timestamp;
+  private Date creationTime;
   private String globalTxId;
   private String localTxId;
   private String parentTxId;
@@ -28,8 +30,8 @@ public class TxEvent {
   private TxEvent() {
   }
 
-  public TxEvent(long timestamp, String globalTxId, String localTxId, String parentTxId, String type, byte[] payloads) {
-    this.timestamp = timestamp;
+  public TxEvent(Date creationTime, String globalTxId, String localTxId, String parentTxId, String type, byte[] payloads) {
+    this.creationTime = creationTime;
     this.globalTxId = globalTxId;
     this.localTxId = localTxId;
     this.parentTxId = parentTxId;
@@ -37,8 +39,8 @@ public class TxEvent {
     this.payloads = payloads;
   }
 
-  public long timestamp() {
-    return timestamp;
+  public Date creationTime() {
+    return creationTime;
   }
 
   public String globalTxId() {
diff --git a/alpha/alpha-server/pom.xml b/alpha/alpha-server/pom.xml
index 78723d5..4bc347e 100644
--- a/alpha/alpha-server/pom.xml
+++ b/alpha/alpha-server/pom.xml
@@ -65,6 +65,10 @@
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-data-jpa</artifactId>
     </dependency>
+    <dependency>
+      <groupId>mysql</groupId>
+      <artifactId>mysql-connector-java</artifactId>
+    </dependency>
 
     <dependency>
       <groupId>org.springframework.boot</groupId>
@@ -87,6 +91,34 @@
         <artifactId>swift-maven-plugin</artifactId>
       </plugin>
 -->
+      <!-- mixin plugin configurations declared in another pom,
+      just like importing dependencies managed in another pom -->
+      <plugin>
+        <groupId>com.github.odavid.maven.plugins</groupId>
+        <artifactId>mixin-maven-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-maven-plugin</artifactId>
+      </plugin>
     </plugins>
   </build>
+
+  <profiles>
+    <profile>
+      <id>docker</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>io.fabric8</groupId>
+            <artifactId>docker-maven-plugin</artifactId>
+          </plugin>
+          <plugin>
+            <groupId>org.commonjava.maven.plugins</groupId>
+            <artifactId>directory-maven-plugin</artifactId>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
 </project>
\ No newline at end of file
diff --git a/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/SwiftTxEventEndpointImpl.java b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/SwiftTxEventEndpointImpl.java
index 4fd7d87..3ae39f6 100644
--- a/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/SwiftTxEventEndpointImpl.java
+++ b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/SwiftTxEventEndpointImpl.java
@@ -17,6 +17,8 @@
 
 package io.servicecomb.saga.alpha.server;
 
+import java.util.Date;
+
 import io.servicecomb.saga.alpha.core.TxEvent;
 import io.servicecomb.saga.alpha.core.TxEventRepository;
 import io.servicecomb.saga.pack.contracts.thrift.SwiftTxEvent;
@@ -33,7 +35,7 @@ class SwiftTxEventEndpointImpl implements SwiftTxEventEndpoint {
   @Override
   public void handle(SwiftTxEvent message) {
     eventRepository.save(new TxEvent(
-        message.timestamp(),
+        new Date(message.timestamp()),
         message.globalTxId(),
         message.localTxId(),
         message.parentTxId(),
diff --git a/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/TxEventEnvelope.java b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/TxEventEnvelope.java
index d5428c4..adbb28e 100644
--- a/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/TxEventEnvelope.java
+++ b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/TxEventEnvelope.java
@@ -40,8 +40,8 @@ class TxEventEnvelope {
     this.event = event;
   }
 
-  public long timestamp() {
-    return event.timestamp();
+  public long creationTime() {
+    return event.creationTime().getTime();
   }
 
   String globalTxId() {
diff --git a/alpha/alpha-server/src/main/resources/application.yaml b/alpha/alpha-server/src/main/resources/application.yaml
new file mode 100644
index 0000000..9b166c8
--- /dev/null
+++ b/alpha/alpha-server/src/main/resources/application.yaml
@@ -0,0 +1,31 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements.  See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License.  You may obtain a copy of the License at
+##
+##      http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+spring:
+  profiles: prd
+  datasource:
+    username: saga
+    password: password
+    driver-class-name: com.mysql.jdbc.Driver
+    url: jdbc:mysql://mysql.servicecomb.io:3306/saga?useSSL=false
+    platform: mysql
+    continue-on-error: true
+  jpa:
+    properties:
+      hibernate:
+        dialect: org.hibernate.dialect.MySQL5Dialect
+    hibernate:
+      ddl-auto: none
diff --git a/integration-tests/pom.xml b/alpha/alpha-server/src/main/resources/log4j2.xml
similarity index 50%
copy from integration-tests/pom.xml
copy to alpha/alpha-server/src/main/resources/log4j2.xml
index 8b71db2..cae04cb 100644
--- a/integration-tests/pom.xml
+++ b/alpha/alpha-server/src/main/resources/log4j2.xml
@@ -16,31 +16,15 @@
   ~ 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>io.servicecomb.saga</groupId>
-    <version>0.0.3-SNAPSHOT</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-
-  <groupId>io.servicecomb.saga.tests</groupId>
-  <artifactId>integration-tests</artifactId>
-  <packaging>pom</packaging>
-  <modules>
-    <module>coverage-aggregate</module>
-  </modules>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-deploy-plugin</artifactId>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-
-</project>
+<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/alpha/alpha-server/src/main/resources/schema-mysql.sql b/alpha/alpha-server/src/main/resources/schema-mysql.sql
new file mode 100644
index 0000000..c3175ed
--- /dev/null
+++ b/alpha/alpha-server/src/main/resources/schema-mysql.sql
@@ -0,0 +1,11 @@
+CREATE TABLE IF NOT EXISTS `tx_event_envelope` (
+  `surrogate_id` bigint NOT NULL AUTO_INCREMENT,
+  `creation_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+  `global_tx_id` varchar(36) NOT NULL,
+  `local_tx_id` varchar(36) NOT NULL,
+  `parent_tx_id` varchar(36) DEFAULT NULL,
+  `type` varchar(50) NOT NULL,
+  `payloads` varbinary(10240),
+  PRIMARY KEY (`surrogate_id`),
+  INDEX `running_sagas_index` (`global_tx_id`, `local_tx_id`, `type`)
+) DEFAULT CHARSET=utf8;
diff --git a/integration-tests/coverage-aggregate/pom.xml b/integration-tests/coverage-aggregate/pom.xml
index a32f598..452fc56 100644
--- a/integration-tests/coverage-aggregate/pom.xml
+++ b/integration-tests/coverage-aggregate/pom.xml
@@ -63,6 +63,14 @@
       <groupId>io.servicecomb.saga</groupId>
       <artifactId>omega-transport-resttemplate</artifactId>
     </dependency>
+    <dependency>
+      <groupId>io.servicecomb.saga</groupId>
+      <artifactId>omega-format</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.servicecomb.saga</groupId>
+      <artifactId>alpha-server</artifactId>
+    </dependency>
   </dependencies>
 
   <profiles>
diff --git a/saga-demo/conditional-transaction-demo/conditional-transaction-demo-tests/pom.xml b/integration-tests/pack-tests/pom.xml
similarity index 64%
copy from saga-demo/conditional-transaction-demo/conditional-transaction-demo-tests/pom.xml
copy to integration-tests/pack-tests/pom.xml
index f1a5bba..bc7717c 100644
--- a/saga-demo/conditional-transaction-demo/conditional-transaction-demo-tests/pom.xml
+++ b/integration-tests/pack-tests/pom.xml
@@ -16,18 +16,36 @@
   ~ 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">
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <parent>
-    <artifactId>conditional-transaction-demo</artifactId>
-    <groupId>io.servicecomb.saga.demo</groupId>
+    <artifactId>integration-tests</artifactId>
+    <groupId>io.servicecomb.saga.tests</groupId>
     <version>0.0.3-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
-  <artifactId>conditional-transaction-demo-tests</artifactId>
+  <artifactId>pack-tests</artifactId>
+
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-dependencies</artifactId>
+        <version>${spring.boot.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
 
   <dependencies>
     <dependency>
+      <groupId>io.servicecomb.saga</groupId>
+      <artifactId>omega-spring-starter</artifactId>
+    </dependency>
+    <dependency>
       <groupId>commons-logging</groupId>
       <artifactId>commons-logging</artifactId>
       <version>1.2</version>
@@ -44,6 +62,16 @@
     </dependency>
     <dependency>
       <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-web</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-test</artifactId>
       <scope>test</scope>
     </dependency>
@@ -86,107 +114,19 @@
               </run>
             </image>
             <image>
-              <name>payment:${project.version}</name>
-              <alias>payment</alias>
-              <run>
-                <env>
-                  <JAVA_OPTS />
-                </env>
-                <wait>
-                  <log>Tomcat started on port</log>
-                  <tcp>
-                    <ports>
-                      <port>8080</port>
-                    </ports>
-                  </tcp>
-                  <time>120000</time>
-                </wait>
-                <ports>
-                  <port>payment.port:8080</port>
-                </ports>
-              </run>
-            </image>
-            <image>
-              <name>membership:${project.version}</name>
-              <alias>membership</alias>
-              <run>
-                <env>
-                  <JAVA_OPTS />
-                </env>
-                <wait>
-                  <log>Tomcat started on port</log>
-                  <tcp>
-                    <ports>
-                      <port>8080</port>
-                    </ports>
-                  </tcp>
-                  <time>120000</time>
-                </wait>
-                <ports>
-                  <port>membership.port:8080</port>
-                </ports>
-              </run>
-            </image>
-            <image>
-              <name>inventory:${project.version}</name>
-              <alias>inventory</alias>
-              <run>
-                <env>
-                  <JAVA_OPTS />
-                </env>
-                <wait>
-                  <log>Tomcat started on port</log>
-                  <tcp>
-                    <ports>
-                      <port>8080</port>
-                    </ports>
-                  </tcp>
-                  <time>120000</time>
-                </wait>
-                <ports>
-                  <port>inventory.port:8080</port>
-                </ports>
-              </run>
-            </image>
-            <image>
-              <name>supplier:${project.version}</name>
-              <alias>supplier</alias>
-              <run>
-                <env>
-                  <JAVA_OPTS />
-                </env>
-                <wait>
-                  <log>Tomcat started on port</log>
-                  <tcp>
-                    <ports>
-                      <port>8080</port>
-                    </ports>
-                  </tcp>
-                  <time>120000</time>
-                </wait>
-                <ports>
-                  <port>supplier.port:8080</port>
-                </ports>
-              </run>
-            </image>
-            <image>
-              <name>saga-spring:${project.version}</name>
-              <alias>saga</alias>
+              <name>alpha-server:${project.version}</name>
+              <alias>alpha</alias>
               <run>
                 <env>
                   <JAVA_OPTS>
-                    -Dspring.profiles.active=prd -Dspring.main.webEnvironment=true
+                    -Dspring.profiles.active=prd
                   </JAVA_OPTS>
                 </env>
                 <links>
                   <link>mysql:mysql.servicecomb.io</link>
-                  <link>payment:payment.servicecomb.io</link>
-                  <link>membership:membership.servicecomb.io</link>
-                  <link>inventory:inventory.servicecomb.io</link>
-                  <link>supplier:supplier.servicecomb.io</link>
                 </links>
                 <wait>
-                  <log>Tomcat started on port</log>
+                  <log>Started [a-zA-Z]+ in [0-9.]+ seconds</log>
                   <tcp>
                     <ports>
                       <port>8080</port>
@@ -195,7 +135,7 @@
                   <time>120000</time>
                 </wait>
                 <ports>
-                  <port>saga.port:8080</port>
+                  <port>alpha.port:8080</port>
                 </ports>
                 <dependsOn>
                   <dependsOn>mysql</dependsOn>
@@ -250,11 +190,11 @@
           <plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-failsafe-plugin</artifactId>
-            <version>2.19.1</version>
+            <version>${maven.failsafe.version}</version>
             <configuration>
               <systemPropertyVariables>
                 <saga.address>
-                  http://${docker.hostname}:${saga.port}
+                  http://${docker.hostname}:${alpha.port}
                 </saga.address>
               </systemPropertyVariables>
               <argLine>${jacoco.failsafe.argLine}</argLine>
@@ -302,4 +242,4 @@
     </profile>
   </profiles>
 
-</project>
+</project>
\ No newline at end of file
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageDeserializer.java b/integration-tests/pack-tests/src/test/java/io/servicecomb/saga/integration/pack/tests/GreetingApplication.java
similarity index 66%
copy from omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageDeserializer.java
copy to integration-tests/pack-tests/src/test/java/io/servicecomb/saga/integration/pack/tests/GreetingApplication.java
index d4315b3..24bce7a 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageDeserializer.java
+++ b/integration-tests/pack-tests/src/test/java/io/servicecomb/saga/integration/pack/tests/GreetingApplication.java
@@ -15,8 +15,17 @@
  * limitations under the License.
  */
 
-package io.servicecomb.saga.omega.transaction;
+package io.servicecomb.saga.integration.pack.tests;
 
-public interface MessageDeserializer {
-  <T> T deserialize(byte[] message);
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import io.servicecomb.saga.omega.spring.EnableOmega;
+
+@EnableOmega
+@SpringBootApplication
+public class GreetingApplication {
+  public static void main(String[] args) {
+    SpringApplication.run(GreetingApplication.class, args);
+  }
 }
diff --git a/integration-tests/pack-tests/src/test/java/io/servicecomb/saga/integration/pack/tests/GreetingController.java b/integration-tests/pack-tests/src/test/java/io/servicecomb/saga/integration/pack/tests/GreetingController.java
new file mode 100644
index 0000000..11aa0e8
--- /dev/null
+++ b/integration-tests/pack-tests/src/test/java/io/servicecomb/saga/integration/pack/tests/GreetingController.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.servicecomb.saga.integration.pack.tests;
+
+import java.util.UUID;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import io.servicecomb.saga.omega.context.OmegaContext;
+
+@Controller
+@RequestMapping("/")
+public class GreetingController {
+  private final GreetingService greetingService;
+  private final OmegaContext context;
+
+  @Autowired
+  public GreetingController(GreetingService greetingService, OmegaContext context) {
+    this.greetingService = greetingService;
+    this.context = context;
+  }
+
+
+  @GetMapping("/greet")
+  ResponseEntity<String> greet(@RequestParam String name) {
+    // TODO: 2017/12/26 to be removed when tx id retrieval is done
+    context.setGlobalTxId(UUID.randomUUID().toString());
+    context.setLocalTxId(UUID.randomUUID().toString());
+
+    return ResponseEntity.ok(greetingService.greet(name));
+  }
+}
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageDeserializer.java b/integration-tests/pack-tests/src/test/java/io/servicecomb/saga/integration/pack/tests/GreetingService.java
similarity index 67%
copy from omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageDeserializer.java
copy to integration-tests/pack-tests/src/test/java/io/servicecomb/saga/integration/pack/tests/GreetingService.java
index d4315b3..d65899b 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageDeserializer.java
+++ b/integration-tests/pack-tests/src/test/java/io/servicecomb/saga/integration/pack/tests/GreetingService.java
@@ -15,8 +15,20 @@
  * limitations under the License.
  */
 
-package io.servicecomb.saga.omega.transaction;
+package io.servicecomb.saga.integration.pack.tests;
 
-public interface MessageDeserializer {
-  <T> T deserialize(byte[] message);
+import org.springframework.stereotype.Service;
+
+import io.servicecomb.saga.omega.transaction.annotations.Compensable;
+
+@Service
+public class GreetingService {
+  @Compensable(compensationMethod = "goodbye")
+  String greet(String name) {
+    return "Greetings, " + name;
+  }
+
+  String goodbye(String name) {
+    return "Goodbye, " + name;
+  }
 }
diff --git a/integration-tests/pack-tests/src/test/java/io/servicecomb/saga/integration/pack/tests/PackIT.java b/integration-tests/pack-tests/src/test/java/io/servicecomb/saga/integration/pack/tests/PackIT.java
new file mode 100644
index 0000000..ad6bed1
--- /dev/null
+++ b/integration-tests/pack-tests/src/test/java/io/servicecomb/saga/integration/pack/tests/PackIT.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.servicecomb.saga.integration.pack.tests;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import static org.springframework.http.HttpStatus.OK;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import io.servicecomb.saga.omega.context.OmegaContext;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = GreetingApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT, properties = {"alpha.cluster.address=localhost:32782"})
+public class PackIT {
+  @Autowired
+  private TestRestTemplate restTemplate;
+
+  @Autowired
+  private OmegaContext omegaContext;
+
+
+  @Test
+  public void updatesTxStateToAlpha() throws Exception {
+    ResponseEntity<String> entity = restTemplate.getForEntity("/greet?name={name}", String.class, "mike");
+
+    assertThat(entity.getStatusCode(), is(OK));
+    assertThat(entity.getBody(), is("Greetings, mike"));
+  }
+}
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
index 8b71db2..cf1cc99 100644
--- a/integration-tests/pom.xml
+++ b/integration-tests/pom.xml
@@ -29,6 +29,7 @@
   <packaging>pom</packaging>
   <modules>
     <module>coverage-aggregate</module>
+    <module>pack-tests</module>
   </modules>
 
   <build>
diff --git a/omega/omega-connector/omega-connector-thrift/src/main/java/io/servicecomb/saga/omega/connector/thrift/ThriftMessageSender.java b/omega/omega-connector/omega-connector-thrift/src/main/java/io/servicecomb/saga/omega/connector/thrift/ThriftMessageSender.java
index ed44e0c..bbf9bfa 100644
--- a/omega/omega-connector/omega-connector-thrift/src/main/java/io/servicecomb/saga/omega/connector/thrift/ThriftMessageSender.java
+++ b/omega/omega-connector/omega-connector-thrift/src/main/java/io/servicecomb/saga/omega/connector/thrift/ThriftMessageSender.java
@@ -17,17 +17,34 @@
 
 package io.servicecomb.saga.omega.connector.thrift;
 
+import static com.google.common.net.HostAndPort.fromParts;
+
+import java.util.concurrent.ExecutionException;
+
+import com.facebook.nifty.client.FramedClientConnector;
+import com.facebook.swift.service.ThriftClientManager;
+
 import io.servicecomb.saga.omega.transaction.MessageSender;
 import io.servicecomb.saga.omega.transaction.MessageSerializer;
 import io.servicecomb.saga.omega.transaction.TxEvent;
 import io.servicecomb.saga.pack.contracts.thrift.SwiftTxEvent;
 import io.servicecomb.saga.pack.contracts.thrift.SwiftTxEventEndpoint;
 
-class ThriftMessageSender implements MessageSender {
-
+public class ThriftMessageSender implements MessageSender {
+  private static final ThriftClientManager clientManager = new ThriftClientManager();
   private final SwiftTxEventEndpoint eventService;
   private final MessageSerializer serializer;
 
+  public static ThriftMessageSender create(String host, int port, MessageSerializer serializer) {
+    FramedClientConnector connector = new FramedClientConnector(fromParts(host, port));
+    try {
+      SwiftTxEventEndpoint endpoint = clientManager.createClient(connector, SwiftTxEventEndpoint.class).get();
+      return new ThriftMessageSender(endpoint, serializer);
+    } catch (InterruptedException | ExecutionException e) {
+      throw new IllegalStateException("Failed to create transaction event endpoint client to " + host + ":" + port, e);
+    }
+  }
+
   ThriftMessageSender(SwiftTxEventEndpoint eventService, MessageSerializer serializer) {
     this.eventService = eventService;
     this.serializer = serializer;
diff --git a/integration-tests/pom.xml b/omega/omega-format/pom.xml
similarity index 56%
copy from integration-tests/pom.xml
copy to omega/omega-format/pom.xml
index 8b71db2..e7d2dc9 100644
--- a/integration-tests/pom.xml
+++ b/omega/omega-format/pom.xml
@@ -16,31 +16,36 @@
   ~ 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">
+<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>
+    <artifactId>omega</artifactId>
     <groupId>io.servicecomb.saga</groupId>
     <version>0.0.3-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
-  <groupId>io.servicecomb.saga.tests</groupId>
-  <artifactId>integration-tests</artifactId>
-  <packaging>pom</packaging>
-  <modules>
-    <module>coverage-aggregate</module>
-  </modules>
+  <artifactId>omega-format</artifactId>
 
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-deploy-plugin</artifactId>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
+  <dependencies>
+    <dependency>
+      <groupId>io.servicecomb.saga</groupId>
+      <artifactId>omega-transaction</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.github.seanyinx</groupId>
+      <artifactId>unit-scaffolding</artifactId>
+    </dependency>
+  </dependencies>
 
 </project>
diff --git a/omega/omega-format/src/main/java/io/servicecomb/saga/omega/format/NativeMessageFormat.java b/omega/omega-format/src/main/java/io/servicecomb/saga/omega/format/NativeMessageFormat.java
new file mode 100644
index 0000000..14b1d29
--- /dev/null
+++ b/omega/omega-format/src/main/java/io/servicecomb/saga/omega/format/NativeMessageFormat.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.servicecomb.saga.omega.format;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import io.servicecomb.saga.omega.transaction.MessageDeserializer;
+import io.servicecomb.saga.omega.transaction.MessageSerializer;
+import io.servicecomb.saga.omega.transaction.OmegaException;
+import io.servicecomb.saga.omega.transaction.TxEvent;
+
+public class NativeMessageFormat implements MessageSerializer, MessageDeserializer {
+  @Override
+  public byte[] serialize(TxEvent event) {
+    try {
+      ByteArrayOutputStream out = new ByteArrayOutputStream();
+      try (ObjectOutputStream outputStream = new ObjectOutputStream(out)) {
+        outputStream.writeObject(event.payloads());
+        return out.toByteArray();
+      }
+    } catch (IOException e) {
+      throw new OmegaException("Unable to serialize event with global tx id " + event.globalTxId(), e);
+    }
+  }
+
+  @Override
+  public Object[] deserialize(byte[] message) {
+    try (ObjectInputStream inputStream = new ObjectInputStream(new ByteArrayInputStream(message))) {
+      return (Object[]) inputStream.readObject();
+    } catch (IOException | ClassNotFoundException e) {
+      throw new OmegaException("Unable to deserialize message", e);
+    }
+  }
+}
diff --git a/omega/omega-format/src/test/java/io/servicecomb/saga/omega/format/NativeMessageFormatTest.java b/omega/omega-format/src/test/java/io/servicecomb/saga/omega/format/NativeMessageFormatTest.java
new file mode 100644
index 0000000..4c93270
--- /dev/null
+++ b/omega/omega-format/src/test/java/io/servicecomb/saga/omega/format/NativeMessageFormatTest.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.servicecomb.saga.omega.format;
+
+import static com.seanyinx.github.unit.scaffolding.AssertUtils.expectFailing;
+import static java.util.Arrays.asList;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.startsWith;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Test;
+
+import io.servicecomb.saga.omega.transaction.OmegaException;
+import io.servicecomb.saga.omega.transaction.TxEvent;
+
+public class NativeMessageFormatTest {
+
+  private final NativeMessageFormat format = new NativeMessageFormat();
+
+  @Test
+  public void serializeObjectIntoBytes() throws Exception {
+    byte[] bytes = format.serialize(eventOf("hello", "world"));
+
+    Object[] message = format.deserialize(bytes);
+
+    assertThat(asList(message), contains("hello", "world"));
+  }
+
+  @Test
+  public void blowsUpWhenObjectIsNotSerializable() throws Exception {
+    try {
+      format.serialize(eventOf(new NotSerializable()));
+      expectFailing(OmegaException.class);
+    } catch (OmegaException e) {
+      assertThat(e.getMessage(), startsWith("Unable to serialize event with global tx id"));
+    }
+  }
+
+  @Test
+  public void blowsUpWhenObjectIsNotDeserializable() throws Exception {
+    try {
+      format.deserialize(new byte[0]);
+      expectFailing(OmegaException.class);
+    } catch (OmegaException e) {
+      assertThat(e.getMessage(), startsWith("Unable to deserialize message"));
+    }
+  }
+
+  private TxEvent eventOf(Object... payloads) {
+    return new TxEvent(null, null, null, payloads);
+  }
+
+  private static class NotSerializable {
+  }
+}
\ No newline at end of file
diff --git a/omega/pom.xml b/omega/omega-spring-starter/pom.xml
similarity index 54%
copy from omega/pom.xml
copy to omega/omega-spring-starter/pom.xml
index ac4e397..b900a47 100644
--- a/omega/pom.xml
+++ b/omega/omega-spring-starter/pom.xml
@@ -20,42 +20,31 @@
   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>
+    <artifactId>omega</artifactId>
     <groupId>io.servicecomb.saga</groupId>
     <version>0.0.3-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
-  <artifactId>omega</artifactId>
-  <packaging>pom</packaging>
-  <modules>
-    <module>omega-transaction</module>
-    <module>omega-context</module>
-    <module>omega-spring-tx</module>
-    <module>omega-transport</module>
-    <module>omega-connector</module>
-  </modules>
+  <artifactId>omega-spring-starter</artifactId>
 
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot-dependencies</artifactId>
-        <version>${spring.boot.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb.saga</groupId>
-        <artifactId>omega-context</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb.saga</groupId>
-        <artifactId>omega-transaction</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
+  <dependencies>
+    <dependency>
+      <groupId>io.servicecomb.saga</groupId>
+      <artifactId>omega-transport-resttemplate</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.servicecomb.saga</groupId>
+      <artifactId>omega-spring-tx</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.servicecomb.saga</groupId>
+      <artifactId>omega-connector-thrift</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.servicecomb.saga</groupId>
+      <artifactId>omega-format</artifactId>
+    </dependency>
+  </dependencies>
 
-</project>
\ No newline at end of file
+</project>
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageDeserializer.java b/omega/omega-spring-starter/src/main/java/io/servicecomb/saga/omega/spring/EnableOmega.java
similarity index 61%
copy from omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageDeserializer.java
copy to omega/omega-spring-starter/src/main/java/io/servicecomb/saga/omega/spring/EnableOmega.java
index d4315b3..8d5f851 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageDeserializer.java
+++ b/omega/omega-spring-starter/src/main/java/io/servicecomb/saga/omega/spring/EnableOmega.java
@@ -15,8 +15,19 @@
  * limitations under the License.
  */
 
-package io.servicecomb.saga.omega.transaction;
+package io.servicecomb.saga.omega.spring;
 
-public interface MessageDeserializer {
-  <T> T deserialize(byte[] message);
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.context.annotation.Import;
+
+import io.servicecomb.saga.omega.transaction.spring.TransactionAspectConfig;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Import({OmegaSpringConfig.class, TransactionAspectConfig.class})
+public @interface EnableOmega {
 }
diff --git a/omega/omega-spring-starter/src/main/java/io/servicecomb/saga/omega/spring/OmegaSpringConfig.java b/omega/omega-spring-starter/src/main/java/io/servicecomb/saga/omega/spring/OmegaSpringConfig.java
new file mode 100644
index 0000000..ae92123
--- /dev/null
+++ b/omega/omega-spring-starter/src/main/java/io/servicecomb/saga/omega/spring/OmegaSpringConfig.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.servicecomb.saga.omega.spring;
+
+import java.lang.invoke.MethodHandles;
+import java.util.Arrays;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import io.servicecomb.saga.omega.connector.thrift.ThriftMessageSender;
+import io.servicecomb.saga.omega.format.NativeMessageFormat;
+import io.servicecomb.saga.omega.transaction.MessageSender;
+
+@Configuration
+class OmegaSpringConfig {
+  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+  @Bean
+  MessageSender messageSender(@Value("${alpha.cluster.address}") String[] addresses) {
+    // TODO: 2017/12/26 connect to the one with lowest latency
+    for (String address : addresses) {
+      try {
+        String[] pair = address.split(":");
+        return ThriftMessageSender.create(pair[0], Integer.parseInt(pair[1]), new NativeMessageFormat());
+      } catch (Exception e) {
+        log.error("Unable to connect to alpha at {}", address, e);
+      }
+    }
+
+    throw new IllegalArgumentException(
+        "None of the alpha cluster is reachable: " + Arrays.toString(addresses));
+  }
+}
diff --git a/omega/omega-spring-tx/src/main/java/io/servicecomb/saga/omega/transaction/spring/CompensableMethodCheckingCallback.java b/omega/omega-spring-tx/src/main/java/io/servicecomb/saga/omega/transaction/spring/CompensableMethodCheckingCallback.java
index c29061c..23352f4 100644
--- a/omega/omega-spring-tx/src/main/java/io/servicecomb/saga/omega/transaction/spring/CompensableMethodCheckingCallback.java
+++ b/omega/omega-spring-tx/src/main/java/io/servicecomb/saga/omega/transaction/spring/CompensableMethodCheckingCallback.java
@@ -24,6 +24,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.util.ReflectionUtils.MethodCallback;
 
+import io.servicecomb.saga.omega.transaction.OmegaException;
 import io.servicecomb.saga.omega.transaction.annotations.Compensable;
 
 class CompensableMethodCheckingCallback implements MethodCallback {
@@ -47,7 +48,7 @@ class CompensableMethodCheckingCallback implements MethodCallback {
       bean.getClass().getDeclaredMethod(compensationMethod, method.getParameterTypes());
       LOG.debug("Found compensation method [{}] in {}", compensationMethod, bean.getClass().getCanonicalName());
     } catch (NoSuchMethodException e) {
-      throw new IllegalArgumentException(
+      throw new OmegaException(
           "No such compensation method [" + compensationMethod + "] found in " + bean.getClass().getCanonicalName(),
           e);
     }
diff --git a/omega/omega-spring-tx/src/main/java/io/servicecomb/saga/omega/transaction/spring/TransactionAspectConfig.java b/omega/omega-spring-tx/src/main/java/io/servicecomb/saga/omega/transaction/spring/TransactionAspectConfig.java
index f44e66f..59f7d2e 100644
--- a/omega/omega-spring-tx/src/main/java/io/servicecomb/saga/omega/transaction/spring/TransactionAspectConfig.java
+++ b/omega/omega-spring-tx/src/main/java/io/servicecomb/saga/omega/transaction/spring/TransactionAspectConfig.java
@@ -27,7 +27,7 @@ import io.servicecomb.saga.omega.transaction.TransactionAspect;
 
 @Configuration
 @EnableAspectJAutoProxy
-class TransactionAspectConfig {
+public class TransactionAspectConfig {
   @Bean
   OmegaContext omegaContext() {
     return new OmegaContext();
diff --git a/omega/omega-spring-tx/src/test/java/io/servicecomb/saga/omega/transaction/spring/CompensableAnnotationCheckingTest.java b/omega/omega-spring-tx/src/test/java/io/servicecomb/saga/omega/transaction/spring/CompensableAnnotationCheckingTest.java
index e83a621..29698a0 100644
--- a/omega/omega-spring-tx/src/test/java/io/servicecomb/saga/omega/transaction/spring/CompensableAnnotationCheckingTest.java
+++ b/omega/omega-spring-tx/src/test/java/io/servicecomb/saga/omega/transaction/spring/CompensableAnnotationCheckingTest.java
@@ -33,7 +33,7 @@ public class CompensableAnnotationCheckingTest {
       try (ConfigurableApplicationContext ignored = new SpringApplicationBuilder(TransactionTestMain.class)
           .profiles("annotation-checking")
           .run()) {
-        expectFailing(IllegalArgumentException.class);
+        expectFailing(BeanCreationException.class);
       }
     } catch (BeanCreationException e) {
       assertThat(e.getCause().getMessage(), startsWith("No such compensation method [none]"));
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageDeserializer.java b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageDeserializer.java
index d4315b3..e5348f4 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageDeserializer.java
+++ b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageDeserializer.java
@@ -18,5 +18,5 @@
 package io.servicecomb.saga.omega.transaction;
 
 public interface MessageDeserializer {
-  <T> T deserialize(byte[] message);
+  Object[] deserialize(byte[] message);
 }
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageDeserializer.java b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/OmegaException.java
similarity index 85%
copy from omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageDeserializer.java
copy to omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/OmegaException.java
index d4315b3..a67b2ce 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageDeserializer.java
+++ b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/OmegaException.java
@@ -17,6 +17,9 @@
 
 package io.servicecomb.saga.omega.transaction;
 
-public interface MessageDeserializer {
-  <T> T deserialize(byte[] message);
+public class OmegaException extends RuntimeException {
+
+  public OmegaException(String cause, Throwable throwable) {
+    super(cause, throwable);
+  }
 }
diff --git a/omega/pom.xml b/omega/pom.xml
index ac4e397..a0def30 100644
--- a/omega/pom.xml
+++ b/omega/pom.xml
@@ -34,6 +34,8 @@
     <module>omega-spring-tx</module>
     <module>omega-transport</module>
     <module>omega-connector</module>
+    <module>omega-spring-starter</module>
+    <module>omega-format</module>
   </modules>
 
   <dependencyManagement>
diff --git a/pom.xml b/pom.xml
index 026d3df..6668b59 100755
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,6 @@
 
   <modules>
     <module>saga-core</module>
-    <module>integration-tests</module>
     <module>transports</module>
     <module>saga-spring</module>
     <module>docker-build-config</module>
@@ -36,6 +35,7 @@
     <module>omega</module>
     <module>alpha</module>
     <module>pack-contracts</module>
+    <module>integration-tests</module>
   </modules>
 
   <properties>
@@ -50,6 +50,7 @@
     <spring.version>4.3.7.RELEASE</spring.version>
     <akka.version>2.5.6</akka.version>
     <rat.version>0.12</rat.version>
+    <maven.failsafe.version>2.19.1</maven.failsafe.version>
   </properties>
 
   <name>ServiceComb Saga</name>
@@ -152,11 +153,31 @@
       </dependency>
       <dependency>
         <groupId>io.servicecomb.saga</groupId>
+        <artifactId>omega-connector-thrift</artifactId>
+        <version>0.0.3-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>io.servicecomb.saga</groupId>
+        <artifactId>omega-spring-starter</artifactId>
+        <version>0.0.3-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>io.servicecomb.saga</groupId>
+        <artifactId>omega-format</artifactId>
+        <version>0.0.3-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>io.servicecomb.saga</groupId>
         <artifactId>alpha-core</artifactId>
         <version>0.0.3-SNAPSHOT</version>
       </dependency>
       <dependency>
         <groupId>io.servicecomb.saga</groupId>
+        <artifactId>alpha-server</artifactId>
+        <version>0.0.3-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>io.servicecomb.saga</groupId>
         <artifactId>pack-contract-thrift</artifactId>
         <version>0.0.3-SNAPSHOT</version>
       </dependency>
@@ -294,6 +315,10 @@
             <groupId>javax.validation</groupId>
             <artifactId>validation-api</artifactId>
           </exclusion>
+          <exclusion>
+            <groupId>org.apache.bval</groupId>
+            <artifactId>bval-jsr303</artifactId>
+          </exclusion>
         </exclusions>
       </dependency>
 
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
index f1a5bba..a037c14 100644
--- a/saga-demo/conditional-transaction-demo/conditional-transaction-demo-tests/pom.xml
+++ b/saga-demo/conditional-transaction-demo/conditional-transaction-demo-tests/pom.xml
@@ -250,7 +250,7 @@
           <plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-failsafe-plugin</artifactId>
-            <version>2.19.1</version>
+            <version>${maven.failsafe.version}</version>
             <configuration>
               <systemPropertyVariables>
                 <saga.address>
diff --git a/saga-demo/dependency-free-transaction-demo/demo-tests/pom.xml b/saga-demo/dependency-free-transaction-demo/demo-tests/pom.xml
index 6684628..80568fd 100644
--- a/saga-demo/dependency-free-transaction-demo/demo-tests/pom.xml
+++ b/saga-demo/dependency-free-transaction-demo/demo-tests/pom.xml
@@ -282,7 +282,7 @@
           <plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-failsafe-plugin</artifactId>
-            <version>2.19.1</version>
+            <version>${maven.failsafe.version}</version>
             <configuration>
               <systemPropertyVariables>
                 <saga.address>

-- 
To stop receiving notification emails like this one, please contact
"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>.

[incubator-servicecomb-saga] 05/07: SCB-97 made alpha server port configurable with default 8080

Posted by se...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

seanyinx pushed a commit to branch SCB-97_alpha_omega_bonding
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-saga.git

commit 2342a289d93cbe45b0fd15a312afb7a0f1920905
Author: seanyinx <se...@huawei.com>
AuthorDate: Tue Dec 26 11:00:58 2017 +0800

    SCB-97 made alpha server port configurable with default 8080
    
    Signed-off-by: seanyinx <se...@huawei.com>
---
 .../src/main/java/io/servicecomb/saga/alpha/server/AlphaConfig.java  | 5 +++--
 .../java/io/servicecomb/saga/alpha/server/AlphaIntegrationTest.java  | 2 +-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/AlphaConfig.java b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/AlphaConfig.java
index 259f1cb..50d4a8d 100644
--- a/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/AlphaConfig.java
+++ b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/AlphaConfig.java
@@ -19,6 +19,7 @@ package io.servicecomb.saga.alpha.server;
 
 import java.util.concurrent.CompletableFuture;
 
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
@@ -28,10 +29,10 @@ import io.servicecomb.saga.alpha.core.TxEventRepository;
 class AlphaConfig {
 
   @Bean
-  TxEventRepository springTxEventRepository(TxEventEnvelopeRepository eventRepo) {
+  TxEventRepository springTxEventRepository(@Value("${alpha.server.port:8080}") int port, TxEventEnvelopeRepository eventRepo) {
     TxEventRepository eventRepository = new SpringTxEventRepository(eventRepo);
 
-    ThriftStartable startable = new ThriftStartable(8090, new SwiftTxEventEndpointImpl(eventRepository));
+    ThriftStartable startable = new ThriftStartable(port, new SwiftTxEventEndpointImpl(eventRepository));
     CompletableFuture.runAsync(startable::start);
 
     return eventRepository;
diff --git a/alpha/alpha-server/src/test/java/io/servicecomb/saga/alpha/server/AlphaIntegrationTest.java b/alpha/alpha-server/src/test/java/io/servicecomb/saga/alpha/server/AlphaIntegrationTest.java
index 8578bf3..1e1ce99 100644
--- a/alpha/alpha-server/src/test/java/io/servicecomb/saga/alpha/server/AlphaIntegrationTest.java
+++ b/alpha/alpha-server/src/test/java/io/servicecomb/saga/alpha/server/AlphaIntegrationTest.java
@@ -37,7 +37,7 @@ import io.servicecomb.saga.pack.contracts.thrift.SwiftTxEvent;
 import io.servicecomb.saga.pack.contracts.thrift.SwiftTxEventEndpoint;
 
 @RunWith(SpringRunner.class)
-@SpringBootTest(classes = AlphaApplication.class)
+@SpringBootTest(classes = AlphaApplication.class, properties = "alpha.server.port=8090")
 public class AlphaIntegrationTest {
   private static final ThriftClientManager clientManager = new ThriftClientManager();
   private static final String TX_STARTED_EVENT = "TxStartedEvent";

-- 
To stop receiving notification emails like this one, please contact
"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>.

[incubator-servicecomb-saga] 01/07: SCB-96 added request interceptor

Posted by se...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

seanyinx pushed a commit to branch SCB-97_alpha_omega_bonding
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-saga.git

commit 5f83a68613e42c62a096bd62a932d6987007e20e
Author: Eric Lee <da...@huawei.com>
AuthorDate: Mon Dec 25 17:22:34 2017 +0800

    SCB-96 added request interceptor
---
 .../saga/omega/transaction/TxEndedEvent.java       |   4 +-
 .../saga/omega/transaction/TxStartedEvent.java     |   4 +-
 .../omega-transport-resttemplate/pom.xml           |   8 ++
 .../TransactionHandlerInterceptor.java             |  87 ++++++++++++
 .../omega/transport/resttemplate/WebConfig.java    |  50 +++++++
 .../TransactionHandlerInterceptorTest.java         | 152 +++++++++++++++++++++
 6 files changed, 301 insertions(+), 4 deletions(-)

diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEndedEvent.java b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEndedEvent.java
index 6cc8f79..c24c1b3 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEndedEvent.java
+++ b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEndedEvent.java
@@ -17,8 +17,8 @@
 
 package io.servicecomb.saga.omega.transaction;
 
-class TxEndedEvent extends TxEvent {
-  TxEndedEvent(String globalTxId, String localTxId, String parentTxId) {
+public class TxEndedEvent extends TxEvent {
+  public TxEndedEvent(String globalTxId, String localTxId, String parentTxId) {
     super(globalTxId, localTxId, parentTxId);
   }
 }
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxStartedEvent.java b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxStartedEvent.java
index 830104f..c278f54 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxStartedEvent.java
+++ b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxStartedEvent.java
@@ -17,9 +17,9 @@
 
 package io.servicecomb.saga.omega.transaction;
 
-class TxStartedEvent extends TxEvent {
+public class TxStartedEvent extends TxEvent {
 
-  TxStartedEvent(String globalTxId, String localTxId, String parentTxId, Object[] payloads) {
+  public TxStartedEvent(String globalTxId, String localTxId, String parentTxId, Object[] payloads) {
     super(globalTxId, localTxId, parentTxId, payloads);
   }
 }
diff --git a/omega/omega-transport/omega-transport-resttemplate/pom.xml b/omega/omega-transport/omega-transport-resttemplate/pom.xml
index d7115d1..5464337 100644
--- a/omega/omega-transport/omega-transport-resttemplate/pom.xml
+++ b/omega/omega-transport/omega-transport-resttemplate/pom.xml
@@ -38,6 +38,14 @@
       <groupId>org.springframework</groupId>
       <artifactId>spring-web</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-webmvc</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>javax.servlet-api</artifactId>
+    </dependency>
 
     <dependency>
       <groupId>org.springframework</groupId>
diff --git a/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptor.java b/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptor.java
new file mode 100644
index 0000000..56df07d
--- /dev/null
+++ b/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptor.java
@@ -0,0 +1,87 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ */
+
+package io.servicecomb.saga.omega.transport.resttemplate;
+
+import static io.servicecomb.saga.omega.transport.resttemplate.TransactionClientHttpRequestInterceptor.GLOBAL_TX_ID_KEY;
+import static io.servicecomb.saga.omega.transport.resttemplate.TransactionClientHttpRequestInterceptor.LOCAL_TX_ID_KEY;
+
+import java.lang.invoke.MethodHandles;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.ModelAndView;
+
+import io.servicecomb.saga.omega.transaction.MessageSender;
+import io.servicecomb.saga.omega.transaction.MessageSerializer;
+import io.servicecomb.saga.omega.transaction.TxEndedEvent;
+import io.servicecomb.saga.omega.transaction.TxStartedEvent;
+
+public class TransactionHandlerInterceptor implements HandlerInterceptor {
+
+  private static Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+  private final MessageSender sender;
+
+  private final MessageSerializer serializer;
+
+  public TransactionHandlerInterceptor(MessageSender sender, MessageSerializer serializer) {
+    this.sender = sender;
+    this.serializer = serializer;
+  }
+
+  @Override
+  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+    String globalTxId = request.getHeader(GLOBAL_TX_ID_KEY);
+    if (globalTxId == null) {
+      LOG.info("no such header: {}", GLOBAL_TX_ID_KEY);
+    }
+    String localTxId = request.getHeader(LOCAL_TX_ID_KEY);
+    if (localTxId == null) {
+      LOG.info("no such header: {}", LOCAL_TX_ID_KEY);
+    }
+    // TODO: 12/25/2017 which content should be inside payloads?
+    sender.send(serializer.serialize(new TxStartedEvent(globalTxId, localTxId, null, null)));
+    return true;
+  }
+
+  @Override
+  public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
+      ModelAndView modelAndView) throws Exception {
+  }
+
+  @Override
+  public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o,
+      Exception e) throws Exception {
+    String globalTxId = request.getHeader(GLOBAL_TX_ID_KEY);
+    if (globalTxId == null) {
+      LOG.info("no such header: {}", GLOBAL_TX_ID_KEY);
+    }
+    String localTxId = request.getHeader(LOCAL_TX_ID_KEY);
+    if (localTxId == null) {
+      LOG.info("no such header: {}", LOCAL_TX_ID_KEY);
+    }
+    sender.send(serializer.serialize(new TxEndedEvent(globalTxId, localTxId, null)));
+  }
+}
diff --git a/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/WebConfig.java b/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/WebConfig.java
new file mode 100644
index 0000000..7d4fe7f
--- /dev/null
+++ b/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/WebConfig.java
@@ -0,0 +1,50 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ */
+
+package io.servicecomb.saga.omega.transport.resttemplate;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+import io.servicecomb.saga.omega.transaction.MessageSender;
+import io.servicecomb.saga.omega.transaction.MessageSerializer;
+
+@Configuration
+@EnableWebMvc
+public class WebConfig extends WebMvcConfigurerAdapter {
+
+  private MessageSender sender;
+
+  private MessageSerializer serializer;
+
+  @Autowired
+  public WebConfig(MessageSender sender, MessageSerializer serializer) {
+    this.sender = sender;
+    this.serializer = serializer;
+  }
+
+  @Override
+  public void addInterceptors(InterceptorRegistry registry) {
+    registry.addInterceptor(new TransactionHandlerInterceptor(sender, serializer));
+  }
+}
diff --git a/omega/omega-transport/omega-transport-resttemplate/src/test/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptorTest.java b/omega/omega-transport/omega-transport-resttemplate/src/test/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptorTest.java
new file mode 100644
index 0000000..6d447f5
--- /dev/null
+++ b/omega/omega-transport/omega-transport-resttemplate/src/test/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptorTest.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.servicecomb.saga.omega.transport.resttemplate;
+
+import static io.servicecomb.saga.omega.transport.resttemplate.TransactionClientHttpRequestInterceptor.GLOBAL_TX_ID_KEY;
+import static io.servicecomb.saga.omega.transport.resttemplate.TransactionClientHttpRequestInterceptor.LOCAL_TX_ID_KEY;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import io.servicecomb.saga.omega.transaction.MessageSender;
+import io.servicecomb.saga.omega.transaction.MessageSerializer;
+import io.servicecomb.saga.omega.transport.resttemplate.TransactionHandlerInterceptorTest.MessageConfig;
+
+@RunWith(SpringRunner.class)
+@Import({MessageConfig.class})
+public class TransactionHandlerInterceptorTest {
+  private static final String TX_STARTED_EVENT = "TxStartedEvent";
+  private static final String TX_ENDED_EVENT = "TxEndedEvent";
+  private static final String globalTxId = UUID.randomUUID().toString();
+  private static final String localTxId = UUID.randomUUID().toString();
+
+  @Autowired
+  private MessageSender sender;
+
+  @Autowired
+  private MessageSerializer serializer;
+
+  @Autowired
+  private TransactionHandlerInterceptor requestInterceptor;
+
+  @Autowired
+  private List<byte[]> messages;
+
+  private HttpServletRequest request = mock(HttpServletRequest.class);
+
+  private HttpServletResponse response = mock(HttpServletResponse.class);
+
+  @After
+  public void tearDown() throws Exception {
+    messages.clear();
+  }
+
+  @Test
+  public void preInterceptHeaderValueAndSendOut() throws Exception {
+    when(request.getHeader(GLOBAL_TX_ID_KEY)).thenReturn(globalTxId);
+    when(request.getHeader(LOCAL_TX_ID_KEY)).thenReturn(localTxId);
+
+    requestInterceptor.preHandle(request, response, null);
+
+    assertThat(messages.size(), is(1));
+    String deserializedString = new String(messages.get(0));
+    assertThat(deserializedString.contains(TX_STARTED_EVENT), is(true));
+    assertThat(deserializedString.startsWith(globalTxId), is(true));
+    assertThat(deserializedString.contains(localTxId), is(true));
+  }
+
+  @Test
+  public void postInterceptHeaderValueAndSendOut() throws Exception {
+    when(request.getHeader(GLOBAL_TX_ID_KEY)).thenReturn(globalTxId);
+    when(request.getHeader(LOCAL_TX_ID_KEY)).thenReturn(localTxId);
+
+    requestInterceptor.afterCompletion(request, response, null, null);
+
+    assertThat(messages.size(), is(1));
+    String deserializedString = new String(messages.get(0));
+    assertThat(deserializedString.contains(TX_ENDED_EVENT), is(true));
+    assertThat(deserializedString.startsWith(globalTxId), is(true));
+    assertThat(deserializedString.contains(localTxId), is(true));
+  }
+
+  @Configuration
+  static class MessageConfig {
+    private final List<byte[]> messages = new ArrayList<>();
+
+    @Bean
+    List<byte[]> messages() {
+      return messages;
+    }
+
+    @Bean
+    MessageSender sender() {
+      return messages::add;
+    }
+
+    @Bean
+    MessageSerializer serializer() {
+      return event -> {
+        if (TX_STARTED_EVENT.equals(event.type())) {
+          return txStartedEvent(event.globalTxId(),
+              event.localTxId(),
+              event.parentTxId(),
+              event.payloads()).getBytes();
+        }
+        return txEndedEvent(event.globalTxId(),
+            event.localTxId(),
+            event.parentTxId()).getBytes();
+      };
+    }
+
+    @Bean
+    HandlerInterceptor handlerInterceptor(MessageSender sender, MessageSerializer serializer) {
+      return new TransactionHandlerInterceptor(sender, serializer);
+    }
+  }
+
+  private static String txStartedEvent(String globalTxId,
+      String localTxId,
+      String parentTxId,
+      Object[] payloads) {
+    return globalTxId + ":" + localTxId + ":" + parentTxId + ":" + TX_STARTED_EVENT + ":" + Arrays.toString(payloads);
+  }
+
+  private static String txEndedEvent(String globalTxId, String localTxId, String parentTxId) {
+    return globalTxId + ":" + localTxId + ":" + parentTxId + ":" + TX_ENDED_EVENT;
+  }
+}
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>.

[incubator-servicecomb-saga] 03/07: SCB-97 alpha is able to persist received events

Posted by se...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

seanyinx pushed a commit to branch SCB-97_alpha_omega_bonding
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-saga.git

commit 02d8aa0c52e0284cf36acdb8ca336242e412c69a
Author: seanyinx <se...@huawei.com>
AuthorDate: Mon Dec 25 18:34:33 2017 +0800

    SCB-97 alpha is able to persist received events
    
    Signed-off-by: seanyinx <se...@huawei.com>
---
 {omega => alpha/alpha-core}/pom.xml                | 34 +--------
 .../io/servicecomb/saga/alpha/core}/TxEvent.java   | 35 ++++++----
 .../saga/alpha/core/TxEventRepository.java         |  6 +-
 {omega => alpha/alpha-server}/pom.xml              | 70 ++++++++++++++-----
 .../saga/alpha/server/AlphaApplication.java        | 12 +++-
 .../servicecomb/saga/alpha/server/AlphaConfig.java | 26 ++++---
 .../saga/alpha/server/SpringTxEventRepository.java | 18 ++++-
 .../alpha/server/SwiftTxEventEndpointImpl.java     | 46 +++++-------
 .../saga/alpha/server/ThriftStartable.java         | 29 +++++---
 .../saga/alpha/server/TxEventEnvelope.java         | 56 +++++++++------
 .../alpha/server/TxEventEnvelopeRepository.java    |  8 ++-
 .../saga/alpha/server/AlphaIntegrationTest.java    | 81 ++++++++++++++++++++++
 {omega => alpha}/pom.xml                           | 31 ++-------
 .../omega-connector-thrift}/pom.xml                | 69 +++++++++---------
 .../connector/thrift/ThriftMessageSender.java}     | 38 +++++-----
 .../connector/thrift/ThriftMessageSenderTest.java  | 69 ++++++++++++++++++
 omega/{ => omega-connector}/pom.xml                | 32 ++-------
 .../spring/TransactionAspectConfig.java            |  5 +-
 .../spring/TransactionInterceptionTest.java        |  4 +-
 .../saga/omega/transaction/MessageSender.java      |  2 +-
 .../transaction/PostTransactionInterceptor.java    |  6 +-
 .../transaction/PreTransactionInterceptor.java     |  6 +-
 .../saga/omega/transaction/TransactionAspect.java  |  6 +-
 .../saga/omega/transaction/TxEvent.java            | 10 ++-
 .../PostTransactionInterceptorTest.java            |  4 +-
 .../transaction/PreTransactionInterceptorTest.java |  4 +-
 omega/pom.xml                                      |  1 +
 .../pack-contract-thrift}/pom.xml                  | 44 ++++--------
 .../saga/pack/contracts/thrift/SwiftTxEvent.java   | 38 +++++++---
 .../contracts/thrift/SwiftTxEventEndpoint.java     | 12 +++-
 {omega => pack-contracts}/pom.xml                  | 31 +--------
 pom.xml                                            | 40 +++++++++++
 32 files changed, 532 insertions(+), 341 deletions(-)

diff --git a/omega/pom.xml b/alpha/alpha-core/pom.xml
similarity index 55%
copy from omega/pom.xml
copy to alpha/alpha-core/pom.xml
index 7028f46..a2cb3e2 100644
--- a/omega/pom.xml
+++ b/alpha/alpha-core/pom.xml
@@ -20,41 +20,13 @@
   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>
+    <artifactId>alpha</artifactId>
     <groupId>io.servicecomb.saga</groupId>
     <version>0.0.3-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
-  <artifactId>omega</artifactId>
-  <packaging>pom</packaging>
-  <modules>
-    <module>omega-transaction</module>
-    <module>omega-context</module>
-    <module>omega-spring-tx</module>
-    <module>omega-transport</module>
-  </modules>
+  <artifactId>alpha-core</artifactId>
 
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot-dependencies</artifactId>
-        <version>${spring.boot.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb.saga</groupId>
-        <artifactId>omega-context</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb.saga</groupId>
-        <artifactId>omega-transaction</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
 
-</project>
\ No newline at end of file
+</project>
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEvent.java b/alpha/alpha-core/src/main/java/io/servicecomb/saga/alpha/core/TxEvent.java
similarity index 68%
copy from omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEvent.java
copy to alpha/alpha-core/src/main/java/io/servicecomb/saga/alpha/core/TxEvent.java
index 2ab3d75..abd8fbd 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEvent.java
+++ b/alpha/alpha-core/src/main/java/io/servicecomb/saga/alpha/core/TxEvent.java
@@ -15,19 +15,30 @@
  * limitations under the License.
  */
 
-package io.servicecomb.saga.omega.transaction;
+package io.servicecomb.saga.alpha.core;
 
-public abstract class TxEvent {
-  private final String globalTxId;
-  private final String localTxId;
-  private final String parentTxId;
-  private final Object[] payloads;
+public class TxEvent {
+  private long timestamp;
+  private String globalTxId;
+  private String localTxId;
+  private String parentTxId;
+  private String type;
+  private byte[] payloads;
 
-  TxEvent(String globalTxId, String localTxId, String parentTxId, Object... payloads) {
+  private TxEvent() {
+  }
+
+  public TxEvent(long timestamp, String globalTxId, String localTxId, String parentTxId, String type, byte[] payloads) {
+    this.timestamp = timestamp;
+    this.globalTxId = globalTxId;
     this.localTxId = localTxId;
     this.parentTxId = parentTxId;
+    this.type = type;
     this.payloads = payloads;
-    this.globalTxId = globalTxId;
+  }
+
+  public long timestamp() {
+    return timestamp;
   }
 
   public String globalTxId() {
@@ -42,11 +53,11 @@ public abstract class TxEvent {
     return parentTxId;
   }
 
-  public Object[] payloads() {
-    return payloads;
+  public String type() {
+    return type;
   }
 
-  public String type() {
-    return this.getClass().getSimpleName();
+  public byte[] payloads() {
+    return payloads;
   }
 }
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSender.java b/alpha/alpha-core/src/main/java/io/servicecomb/saga/alpha/core/TxEventRepository.java
similarity index 88%
copy from omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSender.java
copy to alpha/alpha-core/src/main/java/io/servicecomb/saga/alpha/core/TxEventRepository.java
index ab7bbaa..08ce832 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSender.java
+++ b/alpha/alpha-core/src/main/java/io/servicecomb/saga/alpha/core/TxEventRepository.java
@@ -15,8 +15,8 @@
  * limitations under the License.
  */
 
-package io.servicecomb.saga.omega.transaction;
+package io.servicecomb.saga.alpha.core;
 
-public interface MessageSender {
-  void send(byte[] message);
+public interface TxEventRepository {
+  void save(TxEvent event);
 }
diff --git a/omega/pom.xml b/alpha/alpha-server/pom.xml
similarity index 52%
copy from omega/pom.xml
copy to alpha/alpha-server/pom.xml
index 7028f46..78723d5 100644
--- a/omega/pom.xml
+++ b/alpha/alpha-server/pom.xml
@@ -20,20 +20,13 @@
   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>
+    <artifactId>alpha</artifactId>
     <groupId>io.servicecomb.saga</groupId>
     <version>0.0.3-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
-  <artifactId>omega</artifactId>
-  <packaging>pom</packaging>
-  <modules>
-    <module>omega-transaction</module>
-    <module>omega-context</module>
-    <module>omega-spring-tx</module>
-    <module>omega-transport</module>
-  </modules>
+  <artifactId>alpha-server</artifactId>
 
   <dependencyManagement>
     <dependencies>
@@ -44,17 +37,56 @@
         <type>pom</type>
         <scope>import</scope>
       </dependency>
-      <dependency>
-        <groupId>io.servicecomb.saga</groupId>
-        <artifactId>omega-context</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb.saga</groupId>
-        <artifactId>omega-transaction</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
     </dependencies>
   </dependencyManagement>
 
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.thrift</groupId>
+      <artifactId>libthrift</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.facebook.swift</groupId>
+      <artifactId>swift-service</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.servicecomb.saga</groupId>
+      <artifactId>pack-contract-thrift</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.servicecomb.saga</groupId>
+      <artifactId>alpha-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-data-jpa</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-test</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.h2database</groupId>
+      <artifactId>h2</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+  </dependencies>
+
+  <build>
+    <plugins>
+<!--
+      <plugin>
+        <groupId>com.facebook.mojo</groupId>
+        <artifactId>swift-maven-plugin</artifactId>
+      </plugin>
+-->
+    </plugins>
+  </build>
 </project>
\ No newline at end of file
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSender.java b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/AlphaApplication.java
similarity index 71%
copy from omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSender.java
copy to alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/AlphaApplication.java
index ab7bbaa..c7cb79c 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSender.java
+++ b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/AlphaApplication.java
@@ -15,8 +15,14 @@
  * limitations under the License.
  */
 
-package io.servicecomb.saga.omega.transaction;
+package io.servicecomb.saga.alpha.server;
 
-public interface MessageSender {
-  void send(byte[] message);
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class AlphaApplication {
+  public static void main(String[] args) {
+    SpringApplication.run(AlphaApplication.class, args);
+  }
 }
diff --git a/omega/omega-spring-tx/src/main/java/io/servicecomb/saga/omega/transaction/spring/TransactionAspectConfig.java b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/AlphaConfig.java
similarity index 58%
copy from omega/omega-spring-tx/src/main/java/io/servicecomb/saga/omega/transaction/spring/TransactionAspectConfig.java
copy to alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/AlphaConfig.java
index 60671d2..259f1cb 100644
--- a/omega/omega-spring-tx/src/main/java/io/servicecomb/saga/omega/transaction/spring/TransactionAspectConfig.java
+++ b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/AlphaConfig.java
@@ -15,27 +15,25 @@
  * limitations under the License.
  */
 
-package io.servicecomb.saga.omega.transaction.spring;
+package io.servicecomb.saga.alpha.server;
+
+import java.util.concurrent.CompletableFuture;
 
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.EnableAspectJAutoProxy;
 
-import io.servicecomb.saga.omega.context.OmegaContext;
-import io.servicecomb.saga.omega.transaction.MessageSender;
-import io.servicecomb.saga.omega.transaction.MessageSerializer;
-import io.servicecomb.saga.omega.transaction.TransactionAspect;
+import io.servicecomb.saga.alpha.core.TxEventRepository;
 
 @Configuration
-@EnableAspectJAutoProxy
-class TransactionAspectConfig {
-  @Bean
-  OmegaContext omegaContext() {
-    return new OmegaContext();
-  }
+class AlphaConfig {
 
   @Bean
-  TransactionAspect transactionAspect(MessageSerializer serializer, MessageSender sender, OmegaContext context) {
-    return new TransactionAspect(serializer, sender, context);
+  TxEventRepository springTxEventRepository(TxEventEnvelopeRepository eventRepo) {
+    TxEventRepository eventRepository = new SpringTxEventRepository(eventRepo);
+
+    ThriftStartable startable = new ThriftStartable(8090, new SwiftTxEventEndpointImpl(eventRepository));
+    CompletableFuture.runAsync(startable::start);
+
+    return eventRepository;
   }
 }
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSender.java b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/SpringTxEventRepository.java
similarity index 63%
copy from omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSender.java
copy to alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/SpringTxEventRepository.java
index ab7bbaa..7925924 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSender.java
+++ b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/SpringTxEventRepository.java
@@ -15,8 +15,20 @@
  * limitations under the License.
  */
 
-package io.servicecomb.saga.omega.transaction;
+package io.servicecomb.saga.alpha.server;
 
-public interface MessageSender {
-  void send(byte[] message);
+import io.servicecomb.saga.alpha.core.TxEvent;
+import io.servicecomb.saga.alpha.core.TxEventRepository;
+
+class SpringTxEventRepository implements TxEventRepository {
+  private final TxEventEnvelopeRepository eventRepo;
+
+  SpringTxEventRepository(TxEventEnvelopeRepository eventRepo) {
+    this.eventRepo = eventRepo;
+  }
+
+  @Override
+  public void save(TxEvent event) {
+    eventRepo.save(new TxEventEnvelope(event));
+  }
 }
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEvent.java b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/SwiftTxEventEndpointImpl.java
similarity index 51%
copy from omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEvent.java
copy to alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/SwiftTxEventEndpointImpl.java
index 2ab3d75..4fd7d87 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEvent.java
+++ b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/SwiftTxEventEndpointImpl.java
@@ -15,38 +15,30 @@
  * limitations under the License.
  */
 
-package io.servicecomb.saga.omega.transaction;
+package io.servicecomb.saga.alpha.server;
 
-public abstract class TxEvent {
-  private final String globalTxId;
-  private final String localTxId;
-  private final String parentTxId;
-  private final Object[] payloads;
+import io.servicecomb.saga.alpha.core.TxEvent;
+import io.servicecomb.saga.alpha.core.TxEventRepository;
+import io.servicecomb.saga.pack.contracts.thrift.SwiftTxEvent;
+import io.servicecomb.saga.pack.contracts.thrift.SwiftTxEventEndpoint;
 
-  TxEvent(String globalTxId, String localTxId, String parentTxId, Object... payloads) {
-    this.localTxId = localTxId;
-    this.parentTxId = parentTxId;
-    this.payloads = payloads;
-    this.globalTxId = globalTxId;
-  }
-
-  public String globalTxId() {
-    return globalTxId;
-  }
+class SwiftTxEventEndpointImpl implements SwiftTxEventEndpoint {
 
-  public String localTxId() {
-    return localTxId;
-  }
-
-  public String parentTxId() {
-    return parentTxId;
-  }
+  private final TxEventRepository eventRepository;
 
-  public Object[] payloads() {
-    return payloads;
+  SwiftTxEventEndpointImpl(TxEventRepository eventRepository) {
+    this.eventRepository = eventRepository;
   }
 
-  public String type() {
-    return this.getClass().getSimpleName();
+  @Override
+  public void handle(SwiftTxEvent message) {
+    eventRepository.save(new TxEvent(
+        message.timestamp(),
+        message.globalTxId(),
+        message.localTxId(),
+        message.parentTxId(),
+        message.type(),
+        message.payloads()
+    ));
   }
 }
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/PreTransactionInterceptor.java b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/ThriftStartable.java
similarity index 53%
copy from omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/PreTransactionInterceptor.java
copy to alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/ThriftStartable.java
index 951d21f..71acc2f 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/PreTransactionInterceptor.java
+++ b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/ThriftStartable.java
@@ -15,18 +15,29 @@
  * limitations under the License.
  */
 
-package io.servicecomb.saga.omega.transaction;
+package io.servicecomb.saga.alpha.server;
 
-class PreTransactionInterceptor {
-  private final MessageSender sender;
-  private final MessageSerializer serializer;
+import java.util.Collections;
 
-  PreTransactionInterceptor(MessageSender sender, MessageSerializer serializer) {
-    this.sender = sender;
-    this.serializer = serializer;
+import com.facebook.swift.codec.ThriftCodecManager;
+import com.facebook.swift.service.ThriftServer;
+import com.facebook.swift.service.ThriftServerConfig;
+import com.facebook.swift.service.ThriftServiceProcessor;
+
+class ThriftStartable {
+  private final ThriftServer server;
+
+  ThriftStartable(int port, Object... services) {
+    server = new ThriftServer(
+        new ThriftServiceProcessor(new ThriftCodecManager(),
+            Collections.emptyList(),
+            services),
+        new ThriftServerConfig().setPort(port));
   }
 
-  void intercept(String globalTxId, String localTxId, String parentTxId, Object... message) {
-    sender.send(serializer.serialize(new TxStartedEvent(globalTxId, localTxId, parentTxId, message)));
+  void start() {
+    Runtime.getRuntime().addShutdownHook(new Thread(server::close));
+
+    server.start();
   }
 }
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEvent.java b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/TxEventEnvelope.java
similarity index 52%
copy from omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEvent.java
copy to alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/TxEventEnvelope.java
index 2ab3d75..d5428c4 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEvent.java
+++ b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/TxEventEnvelope.java
@@ -15,38 +15,52 @@
  * limitations under the License.
  */
 
-package io.servicecomb.saga.omega.transaction;
+package io.servicecomb.saga.alpha.server;
 
-public abstract class TxEvent {
-  private final String globalTxId;
-  private final String localTxId;
-  private final String parentTxId;
-  private final Object[] payloads;
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
 
-  TxEvent(String globalTxId, String localTxId, String parentTxId, Object... payloads) {
-    this.localTxId = localTxId;
-    this.parentTxId = parentTxId;
-    this.payloads = payloads;
-    this.globalTxId = globalTxId;
+import io.servicecomb.saga.alpha.core.TxEvent;
+
+@Entity
+class TxEventEnvelope {
+  @Id
+  @GeneratedValue
+  private long surrogateId;
+
+  @Embedded
+  private TxEvent event;
+
+  private TxEventEnvelope() {
+  }
+
+  TxEventEnvelope(TxEvent event) {
+    this.event = event;
+  }
+
+  public long timestamp() {
+    return event.timestamp();
   }
 
-  public String globalTxId() {
-    return globalTxId;
+  String globalTxId() {
+    return event.globalTxId();
   }
 
-  public String localTxId() {
-    return localTxId;
+  String localTxId() {
+    return event.localTxId();
   }
 
-  public String parentTxId() {
-    return parentTxId;
+  String parentTxId() {
+    return event.parentTxId();
   }
 
-  public Object[] payloads() {
-    return payloads;
+  String type() {
+    return event.type();
   }
 
-  public String type() {
-    return this.getClass().getSimpleName();
+  byte[] payloads() {
+    return event.payloads();
   }
 }
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSender.java b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/TxEventEnvelopeRepository.java
similarity index 76%
copy from omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSender.java
copy to alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/TxEventEnvelopeRepository.java
index ab7bbaa..3e46de3 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSender.java
+++ b/alpha/alpha-server/src/main/java/io/servicecomb/saga/alpha/server/TxEventEnvelopeRepository.java
@@ -15,8 +15,10 @@
  * limitations under the License.
  */
 
-package io.servicecomb.saga.omega.transaction;
+package io.servicecomb.saga.alpha.server;
 
-public interface MessageSender {
-  void send(byte[] message);
+import org.springframework.data.repository.CrudRepository;
+
+interface TxEventEnvelopeRepository extends CrudRepository<TxEventEnvelope, Long> {
+  TxEventEnvelope findByEventGlobalTxId(String globalTxId);
 }
diff --git a/alpha/alpha-server/src/test/java/io/servicecomb/saga/alpha/server/AlphaIntegrationTest.java b/alpha/alpha-server/src/test/java/io/servicecomb/saga/alpha/server/AlphaIntegrationTest.java
new file mode 100644
index 0000000..8578bf3
--- /dev/null
+++ b/alpha/alpha-server/src/test/java/io/servicecomb/saga/alpha/server/AlphaIntegrationTest.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.servicecomb.saga.alpha.server;
+
+import static com.google.common.net.HostAndPort.fromParts;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.UUID;
+
+import org.junit.AfterClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.facebook.nifty.client.FramedClientConnector;
+import com.facebook.swift.service.ThriftClientManager;
+
+import io.servicecomb.saga.pack.contracts.thrift.SwiftTxEvent;
+import io.servicecomb.saga.pack.contracts.thrift.SwiftTxEventEndpoint;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = AlphaApplication.class)
+public class AlphaIntegrationTest {
+  private static final ThriftClientManager clientManager = new ThriftClientManager();
+  private static final String TX_STARTED_EVENT = "TxStartedEvent";
+  private static final String payload = "hello world";
+
+  private final int port = 8090;
+
+  private final String globalTxId = UUID.randomUUID().toString();
+  private final String localTxId = UUID.randomUUID().toString();
+  private final String parentTxId = UUID.randomUUID().toString();
+
+  @Autowired
+  private TxEventEnvelopeRepository eventRepo;
+
+  @AfterClass
+  public static void tearDown() throws Exception {
+    clientManager.close();
+  }
+
+  @Test
+  public void persistsEvent() throws Exception {
+    FramedClientConnector connector = new FramedClientConnector(fromParts("localhost", port));
+    SwiftTxEventEndpoint endpoint = clientManager.createClient(connector, SwiftTxEventEndpoint.class).get();
+
+    endpoint.handle(new SwiftTxEvent(
+        System.currentTimeMillis(),
+        globalTxId,
+        localTxId,
+        parentTxId,
+        TX_STARTED_EVENT,
+        payload.getBytes()));
+
+    TxEventEnvelope envelope = eventRepo.findByEventGlobalTxId(globalTxId);
+
+    assertThat(envelope.globalTxId(), is(globalTxId));
+    assertThat(envelope.localTxId(), is(localTxId));
+    assertThat(envelope.parentTxId(), is(parentTxId));
+    assertThat(envelope.type(), is(TX_STARTED_EVENT));
+    assertThat(envelope.payloads(), is(payload.getBytes()));
+  }
+}
diff --git a/omega/pom.xml b/alpha/pom.xml
similarity index 59%
copy from omega/pom.xml
copy to alpha/pom.xml
index 7028f46..942a109 100644
--- a/omega/pom.xml
+++ b/alpha/pom.xml
@@ -26,35 +26,12 @@
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
-  <artifactId>omega</artifactId>
+  <artifactId>alpha</artifactId>
   <packaging>pom</packaging>
   <modules>
-    <module>omega-transaction</module>
-    <module>omega-context</module>
-    <module>omega-spring-tx</module>
-    <module>omega-transport</module>
+    <module>alpha-core</module>
+    <module>alpha-server</module>
   </modules>
 
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot-dependencies</artifactId>
-        <version>${spring.boot.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb.saga</groupId>
-        <artifactId>omega-context</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb.saga</groupId>
-        <artifactId>omega-transaction</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
 
-</project>
\ No newline at end of file
+</project>
diff --git a/omega/pom.xml b/omega/omega-connector/omega-connector-thrift/pom.xml
similarity index 52%
copy from omega/pom.xml
copy to omega/omega-connector/omega-connector-thrift/pom.xml
index 7028f46..ae64b4a 100644
--- a/omega/pom.xml
+++ b/omega/omega-connector/omega-connector-thrift/pom.xml
@@ -20,41 +20,48 @@
   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>
+    <artifactId>omega-connector</artifactId>
     <groupId>io.servicecomb.saga</groupId>
     <version>0.0.3-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
-  <artifactId>omega</artifactId>
-  <packaging>pom</packaging>
-  <modules>
-    <module>omega-transaction</module>
-    <module>omega-context</module>
-    <module>omega-spring-tx</module>
-    <module>omega-transport</module>
-  </modules>
+  <artifactId>omega-connector-thrift</artifactId>
 
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot-dependencies</artifactId>
-        <version>${spring.boot.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb.saga</groupId>
-        <artifactId>omega-context</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb.saga</groupId>
-        <artifactId>omega-transaction</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.thrift</groupId>
+      <artifactId>libthrift</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.facebook.swift</groupId>
+      <artifactId>swift-service</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.servicecomb.saga</groupId>
+      <artifactId>pack-contract-thrift</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>io.servicecomb.saga</groupId>
+      <artifactId>omega-transaction</artifactId>
+    </dependency>
 
-</project>
\ No newline at end of file
+    <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>com.github.seanyinx</groupId>
+      <artifactId>unit-scaffolding</artifactId>
+    </dependency>
+  </dependencies>
+
+</project>
diff --git a/omega/omega-spring-tx/src/main/java/io/servicecomb/saga/omega/transaction/spring/TransactionAspectConfig.java b/omega/omega-connector/omega-connector-thrift/src/main/java/io/servicecomb/saga/omega/connector/thrift/ThriftMessageSender.java
similarity index 53%
copy from omega/omega-spring-tx/src/main/java/io/servicecomb/saga/omega/transaction/spring/TransactionAspectConfig.java
copy to omega/omega-connector/omega-connector-thrift/src/main/java/io/servicecomb/saga/omega/connector/thrift/ThriftMessageSender.java
index 60671d2..ed44e0c 100644
--- a/omega/omega-spring-tx/src/main/java/io/servicecomb/saga/omega/transaction/spring/TransactionAspectConfig.java
+++ b/omega/omega-connector/omega-connector-thrift/src/main/java/io/servicecomb/saga/omega/connector/thrift/ThriftMessageSender.java
@@ -15,27 +15,33 @@
  * limitations under the License.
  */
 
-package io.servicecomb.saga.omega.transaction.spring;
+package io.servicecomb.saga.omega.connector.thrift;
 
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.EnableAspectJAutoProxy;
-
-import io.servicecomb.saga.omega.context.OmegaContext;
 import io.servicecomb.saga.omega.transaction.MessageSender;
 import io.servicecomb.saga.omega.transaction.MessageSerializer;
-import io.servicecomb.saga.omega.transaction.TransactionAspect;
+import io.servicecomb.saga.omega.transaction.TxEvent;
+import io.servicecomb.saga.pack.contracts.thrift.SwiftTxEvent;
+import io.servicecomb.saga.pack.contracts.thrift.SwiftTxEventEndpoint;
+
+class ThriftMessageSender implements MessageSender {
+
+  private final SwiftTxEventEndpoint eventService;
+  private final MessageSerializer serializer;
 
-@Configuration
-@EnableAspectJAutoProxy
-class TransactionAspectConfig {
-  @Bean
-  OmegaContext omegaContext() {
-    return new OmegaContext();
+  ThriftMessageSender(SwiftTxEventEndpoint eventService, MessageSerializer serializer) {
+    this.eventService = eventService;
+    this.serializer = serializer;
   }
 
-  @Bean
-  TransactionAspect transactionAspect(MessageSerializer serializer, MessageSender sender, OmegaContext context) {
-    return new TransactionAspect(serializer, sender, context);
+  @Override
+  public void send(TxEvent event) {
+    eventService.handle(new SwiftTxEvent(
+        event.timestamp(),
+        event.globalTxId(),
+        event.localTxId(),
+        event.parentTxId(),
+        event.type(),
+        serializer.serialize(event)
+    ));
   }
 }
diff --git a/omega/omega-connector/omega-connector-thrift/src/test/java/io/servicecomb/saga/omega/connector/thrift/ThriftMessageSenderTest.java b/omega/omega-connector/omega-connector-thrift/src/test/java/io/servicecomb/saga/omega/connector/thrift/ThriftMessageSenderTest.java
new file mode 100644
index 0000000..3e1f833
--- /dev/null
+++ b/omega/omega-connector/omega-connector-thrift/src/test/java/io/servicecomb/saga/omega/connector/thrift/ThriftMessageSenderTest.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.servicecomb.saga.omega.connector.thrift;
+
+import static com.seanyinx.github.unit.scaffolding.Randomness.uniquify;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import org.junit.Test;
+
+import io.servicecomb.saga.omega.transaction.MessageSerializer;
+import io.servicecomb.saga.omega.transaction.TxEvent;
+import io.servicecomb.saga.pack.contracts.thrift.SwiftTxEvent;
+import io.servicecomb.saga.pack.contracts.thrift.SwiftTxEventEndpoint;
+
+public class ThriftMessageSenderTest {
+
+  private final String globalTxId = uniquify("global tx id");
+  private final String localTxId = uniquify("local tx id");
+  private final String parentTxId = uniquify("parent tx id");
+  private final String payload1 = uniquify("payload1");
+  private final String payload2 = uniquify("payload2");
+
+  private SwiftTxEvent swiftTxEvent;
+
+  private final MessageSerializer serializer = (event) -> {
+    try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
+      for (Object o : event.payloads()) {
+        stream.write(o.toString().getBytes());
+      }
+      return stream.toByteArray();
+    } catch (IOException e) {
+      throw new IllegalStateException(e);
+    }
+  };
+
+  private final SwiftTxEventEndpoint eventService = (event) -> swiftTxEvent = event;
+  private final ThriftMessageSender messageSender = new ThriftMessageSender(eventService, serializer);
+
+  @Test
+  public void sendSerializedEvent() throws Exception {
+    TxEvent event = new TxEvent(globalTxId, localTxId, parentTxId, payload1, payload2);
+
+    messageSender.send(event);
+
+    assertThat(swiftTxEvent.globalTxId(), is(event.globalTxId()));
+    assertThat(swiftTxEvent.localTxId(), is(event.localTxId()));
+    assertThat(swiftTxEvent.parentTxId(), is(event.parentTxId()));
+    assertThat(swiftTxEvent.payloads(), is(serializer.serialize(event)));
+  }
+}
diff --git a/omega/pom.xml b/omega/omega-connector/pom.xml
similarity index 57%
copy from omega/pom.xml
copy to omega/omega-connector/pom.xml
index 7028f46..21203b3 100644
--- a/omega/pom.xml
+++ b/omega/omega-connector/pom.xml
@@ -20,41 +20,17 @@
   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>
+    <artifactId>omega</artifactId>
     <groupId>io.servicecomb.saga</groupId>
     <version>0.0.3-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
-  <artifactId>omega</artifactId>
+  <artifactId>omega-connector</artifactId>
   <packaging>pom</packaging>
   <modules>
-    <module>omega-transaction</module>
-    <module>omega-context</module>
-    <module>omega-spring-tx</module>
-    <module>omega-transport</module>
+    <module>omega-connector-thrift</module>
   </modules>
 
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot-dependencies</artifactId>
-        <version>${spring.boot.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb.saga</groupId>
-        <artifactId>omega-context</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb.saga</groupId>
-        <artifactId>omega-transaction</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
 
-</project>
\ No newline at end of file
+</project>
diff --git a/omega/omega-spring-tx/src/main/java/io/servicecomb/saga/omega/transaction/spring/TransactionAspectConfig.java b/omega/omega-spring-tx/src/main/java/io/servicecomb/saga/omega/transaction/spring/TransactionAspectConfig.java
index 60671d2..f44e66f 100644
--- a/omega/omega-spring-tx/src/main/java/io/servicecomb/saga/omega/transaction/spring/TransactionAspectConfig.java
+++ b/omega/omega-spring-tx/src/main/java/io/servicecomb/saga/omega/transaction/spring/TransactionAspectConfig.java
@@ -23,7 +23,6 @@ import org.springframework.context.annotation.EnableAspectJAutoProxy;
 
 import io.servicecomb.saga.omega.context.OmegaContext;
 import io.servicecomb.saga.omega.transaction.MessageSender;
-import io.servicecomb.saga.omega.transaction.MessageSerializer;
 import io.servicecomb.saga.omega.transaction.TransactionAspect;
 
 @Configuration
@@ -35,7 +34,7 @@ class TransactionAspectConfig {
   }
 
   @Bean
-  TransactionAspect transactionAspect(MessageSerializer serializer, MessageSender sender, OmegaContext context) {
-    return new TransactionAspect(serializer, sender, context);
+  TransactionAspect transactionAspect(MessageSender sender, OmegaContext context) {
+    return new TransactionAspect(sender, context);
   }
 }
diff --git a/omega/omega-spring-tx/src/test/java/io/servicecomb/saga/omega/transaction/spring/TransactionInterceptionTest.java b/omega/omega-spring-tx/src/test/java/io/servicecomb/saga/omega/transaction/spring/TransactionInterceptionTest.java
index dc80f2f..2ba1785 100644
--- a/omega/omega-spring-tx/src/test/java/io/servicecomb/saga/omega/transaction/spring/TransactionInterceptionTest.java
+++ b/omega/omega-spring-tx/src/test/java/io/servicecomb/saga/omega/transaction/spring/TransactionInterceptionTest.java
@@ -128,8 +128,8 @@ public class TransactionInterceptionTest {
     }
 
     @Bean
-    MessageSender sender() {
-      return messages::add;
+    MessageSender sender(MessageSerializer serializer) {
+      return (event) -> messages.add(serializer.serialize(event));
     }
 
     @Bean
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSender.java b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSender.java
index ab7bbaa..1cb8362 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSender.java
+++ b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSender.java
@@ -18,5 +18,5 @@
 package io.servicecomb.saga.omega.transaction;
 
 public interface MessageSender {
-  void send(byte[] message);
+  void send(TxEvent event);
 }
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/PostTransactionInterceptor.java b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/PostTransactionInterceptor.java
index 2cd8ee2..a359ee2 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/PostTransactionInterceptor.java
+++ b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/PostTransactionInterceptor.java
@@ -19,14 +19,12 @@ package io.servicecomb.saga.omega.transaction;
 
 class PostTransactionInterceptor {
   private final MessageSender sender;
-  private final MessageSerializer serializer;
 
-  PostTransactionInterceptor(MessageSender sender, MessageSerializer serializer) {
+  PostTransactionInterceptor(MessageSender sender) {
     this.sender = sender;
-    this.serializer = serializer;
   }
 
   void intercept(String globalTxId, String localTxId, String parentTxId) {
-    sender.send(serializer.serialize(new TxEndedEvent(globalTxId, localTxId, parentTxId)));
+    sender.send(new TxEndedEvent(globalTxId, localTxId, parentTxId));
   }
 }
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/PreTransactionInterceptor.java b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/PreTransactionInterceptor.java
index 951d21f..2c49d48 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/PreTransactionInterceptor.java
+++ b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/PreTransactionInterceptor.java
@@ -19,14 +19,12 @@ package io.servicecomb.saga.omega.transaction;
 
 class PreTransactionInterceptor {
   private final MessageSender sender;
-  private final MessageSerializer serializer;
 
-  PreTransactionInterceptor(MessageSender sender, MessageSerializer serializer) {
+  PreTransactionInterceptor(MessageSender sender) {
     this.sender = sender;
-    this.serializer = serializer;
   }
 
   void intercept(String globalTxId, String localTxId, String parentTxId, Object... message) {
-    sender.send(serializer.serialize(new TxStartedEvent(globalTxId, localTxId, parentTxId, message)));
+    sender.send(new TxStartedEvent(globalTxId, localTxId, parentTxId, message));
   }
 }
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TransactionAspect.java b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TransactionAspect.java
index 6d13a04..f78ed31 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TransactionAspect.java
+++ b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TransactionAspect.java
@@ -37,10 +37,10 @@ public class TransactionAspect {
   private final PostTransactionInterceptor postTransactionInterceptor;
   private final OmegaContext context;
 
-  public TransactionAspect(MessageSerializer serializer, MessageSender sender, OmegaContext context) {
+  public TransactionAspect(MessageSender sender, OmegaContext context) {
     this.context = context;
-    this.preTransactionInterceptor = new PreTransactionInterceptor(sender, serializer);
-    this.postTransactionInterceptor = new PostTransactionInterceptor(sender, serializer);
+    this.preTransactionInterceptor = new PreTransactionInterceptor(sender);
+    this.postTransactionInterceptor = new PostTransactionInterceptor(sender);
   }
 
   @Around("execution(@io.servicecomb.saga.omega.transaction.annotations.Compensable * *(..)) && @annotation(compensable)")
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEvent.java b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEvent.java
index 2ab3d75..b53e64c 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEvent.java
+++ b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEvent.java
@@ -17,19 +17,25 @@
 
 package io.servicecomb.saga.omega.transaction;
 
-public abstract class TxEvent {
+public class TxEvent {
+  private final long timestamp;
   private final String globalTxId;
   private final String localTxId;
   private final String parentTxId;
   private final Object[] payloads;
 
-  TxEvent(String globalTxId, String localTxId, String parentTxId, Object... payloads) {
+  public TxEvent(String globalTxId, String localTxId, String parentTxId, Object... payloads) {
+    this.timestamp = System.currentTimeMillis();
     this.localTxId = localTxId;
     this.parentTxId = parentTxId;
     this.payloads = payloads;
     this.globalTxId = globalTxId;
   }
 
+  public long timestamp() {
+    return timestamp;
+  }
+
   public String globalTxId() {
     return globalTxId;
   }
diff --git a/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/PostTransactionInterceptorTest.java b/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/PostTransactionInterceptorTest.java
index a15e6d1..508c987 100644
--- a/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/PostTransactionInterceptorTest.java
+++ b/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/PostTransactionInterceptorTest.java
@@ -32,10 +32,10 @@ public class PostTransactionInterceptorTest {
   private final String localTxId = UUID.randomUUID().toString();
   private final String parentTxId = UUID.randomUUID().toString();
 
-  private final MessageSender sender = messages::add;
   private final MessageSerializer serializer = event -> serialize(globalTxId, localTxId, parentTxId);
+  private final MessageSender sender = (msg) -> messages.add(serializer.serialize(msg));
 
-  private final PostTransactionInterceptor interceptor = new PostTransactionInterceptor(sender, serializer);
+  private final PostTransactionInterceptor interceptor = new PostTransactionInterceptor(sender);
 
   private byte[] serialize(String globalTxId, String localTxId, String parentTxId) {
     return (globalTxId + ":" + localTxId + ":" + parentTxId).getBytes();
diff --git a/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/PreTransactionInterceptorTest.java b/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/PreTransactionInterceptorTest.java
index 7d335ad..0fcf64e 100644
--- a/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/PreTransactionInterceptorTest.java
+++ b/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/PreTransactionInterceptorTest.java
@@ -33,7 +33,6 @@ public class PreTransactionInterceptorTest {
   private final String localTxId = UUID.randomUUID().toString();
   private final String parentTxId = UUID.randomUUID().toString();
 
-  private final MessageSender sender = messages::add;
   private final MessageSerializer serializer = event -> {
     if (event.payloads()[0] instanceof String) {
       String message = (String) event.payloads()[0];
@@ -41,9 +40,10 @@ public class PreTransactionInterceptorTest {
     }
     throw new IllegalArgumentException("Expected instance of String, but was " + event.getClass());
   };
+  private final MessageSender sender = (msg) -> messages.add(serializer.serialize(msg));
 
   private final String message = uniquify("message");
-  private final PreTransactionInterceptor interceptor = new PreTransactionInterceptor(sender, serializer);
+  private final PreTransactionInterceptor interceptor = new PreTransactionInterceptor(sender);
 
   private byte[] serialize(String globalTxId, String localTxId, String parentTxId, String message) {
     return (globalTxId + ":" + localTxId + ":" + parentTxId + ":" + message).getBytes();
diff --git a/omega/pom.xml b/omega/pom.xml
index 7028f46..ac4e397 100644
--- a/omega/pom.xml
+++ b/omega/pom.xml
@@ -33,6 +33,7 @@
     <module>omega-context</module>
     <module>omega-spring-tx</module>
     <module>omega-transport</module>
+    <module>omega-connector</module>
   </modules>
 
   <dependencyManagement>
diff --git a/omega/pom.xml b/pack-contracts/pack-contract-thrift/pom.xml
similarity index 55%
copy from omega/pom.xml
copy to pack-contracts/pack-contract-thrift/pom.xml
index 7028f46..051aaf1 100644
--- a/omega/pom.xml
+++ b/pack-contracts/pack-contract-thrift/pom.xml
@@ -20,41 +20,23 @@
   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>
+    <artifactId>pack-contracts</artifactId>
     <groupId>io.servicecomb.saga</groupId>
     <version>0.0.3-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
-  <artifactId>omega</artifactId>
-  <packaging>pom</packaging>
-  <modules>
-    <module>omega-transaction</module>
-    <module>omega-context</module>
-    <module>omega-spring-tx</module>
-    <module>omega-transport</module>
-  </modules>
+  <artifactId>pack-contract-thrift</artifactId>
 
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot-dependencies</artifactId>
-        <version>${spring.boot.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb.saga</groupId>
-        <artifactId>omega-context</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb.saga</groupId>
-        <artifactId>omega-transaction</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.thrift</groupId>
+      <artifactId>libthrift</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.facebook.swift</groupId>
+      <artifactId>swift-service</artifactId>
+    </dependency>
+  </dependencies>
 
-</project>
\ No newline at end of file
+</project>
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEvent.java b/pack-contracts/pack-contract-thrift/src/main/java/io/servicecomb/saga/pack/contracts/thrift/SwiftTxEvent.java
similarity index 62%
copy from omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEvent.java
copy to pack-contracts/pack-contract-thrift/src/main/java/io/servicecomb/saga/pack/contracts/thrift/SwiftTxEvent.java
index 2ab3d75..75f6e12 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEvent.java
+++ b/pack-contracts/pack-contract-thrift/src/main/java/io/servicecomb/saga/pack/contracts/thrift/SwiftTxEvent.java
@@ -15,38 +15,58 @@
  * limitations under the License.
  */
 
-package io.servicecomb.saga.omega.transaction;
+package io.servicecomb.saga.pack.contracts.thrift;
 
-public abstract class TxEvent {
+import com.facebook.swift.codec.ThriftConstructor;
+import com.facebook.swift.codec.ThriftField;
+import com.facebook.swift.codec.ThriftStruct;
+
+@ThriftStruct("TxEvent")
+public class SwiftTxEvent {
+  private final long timestamp;
   private final String globalTxId;
   private final String localTxId;
   private final String parentTxId;
-  private final Object[] payloads;
+  private final String type;
+  private final byte[] payloads;
 
-  TxEvent(String globalTxId, String localTxId, String parentTxId, Object... payloads) {
+  @ThriftConstructor
+  public SwiftTxEvent(long timestamp, String globalTxId, String localTxId, String parentTxId, String type, byte[] payloads) {
+    this.timestamp = timestamp;
+    this.globalTxId = globalTxId;
     this.localTxId = localTxId;
     this.parentTxId = parentTxId;
+    this.type = type;
     this.payloads = payloads;
-    this.globalTxId = globalTxId;
   }
 
+  @ThriftField(1)
+  public long timestamp() {
+    return timestamp;
+  }
+
+  @ThriftField(2)
   public String globalTxId() {
     return globalTxId;
   }
 
+  @ThriftField(3)
   public String localTxId() {
     return localTxId;
   }
 
+  @ThriftField(4)
   public String parentTxId() {
     return parentTxId;
   }
 
-  public Object[] payloads() {
-    return payloads;
+  @ThriftField(5)
+  public String type() {
+    return type;
   }
 
-  public String type() {
-    return this.getClass().getSimpleName();
+  @ThriftField(6)
+  public byte[] payloads() {
+    return payloads;
   }
 }
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSender.java b/pack-contracts/pack-contract-thrift/src/main/java/io/servicecomb/saga/pack/contracts/thrift/SwiftTxEventEndpoint.java
similarity index 74%
copy from omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSender.java
copy to pack-contracts/pack-contract-thrift/src/main/java/io/servicecomb/saga/pack/contracts/thrift/SwiftTxEventEndpoint.java
index ab7bbaa..beff7bc 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSender.java
+++ b/pack-contracts/pack-contract-thrift/src/main/java/io/servicecomb/saga/pack/contracts/thrift/SwiftTxEventEndpoint.java
@@ -15,8 +15,14 @@
  * limitations under the License.
  */
 
-package io.servicecomb.saga.omega.transaction;
+package io.servicecomb.saga.pack.contracts.thrift;
 
-public interface MessageSender {
-  void send(byte[] message);
+import com.facebook.swift.service.ThriftMethod;
+import com.facebook.swift.service.ThriftService;
+
+@ThriftService("TxEventEndpoint")
+public interface SwiftTxEventEndpoint {
+
+  @ThriftMethod
+  void handle(SwiftTxEvent message);
 }
diff --git a/omega/pom.xml b/pack-contracts/pom.xml
similarity index 59%
copy from omega/pom.xml
copy to pack-contracts/pom.xml
index 7028f46..cc035dd 100644
--- a/omega/pom.xml
+++ b/pack-contracts/pom.xml
@@ -26,35 +26,10 @@
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
-  <artifactId>omega</artifactId>
+  <artifactId>pack-contracts</artifactId>
   <packaging>pom</packaging>
   <modules>
-    <module>omega-transaction</module>
-    <module>omega-context</module>
-    <module>omega-spring-tx</module>
-    <module>omega-transport</module>
+    <module>pack-contract-thrift</module>
   </modules>
 
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot-dependencies</artifactId>
-        <version>${spring.boot.version}</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb.saga</groupId>
-        <artifactId>omega-context</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
-      <dependency>
-        <groupId>io.servicecomb.saga</groupId>
-        <artifactId>omega-transaction</artifactId>
-        <version>0.0.3-SNAPSHOT</version>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
-
-</project>
\ No newline at end of file
+</project>
diff --git a/pom.xml b/pom.xml
index 0c36c82..026d3df 100755
--- a/pom.xml
+++ b/pom.xml
@@ -34,6 +34,8 @@
     <module>saga-discovery</module>
     <module>saga-web</module>
     <module>omega</module>
+    <module>alpha</module>
+    <module>pack-contracts</module>
   </modules>
 
   <properties>
@@ -149,6 +151,16 @@
         <version>0.0.3-SNAPSHOT</version>
       </dependency>
       <dependency>
+        <groupId>io.servicecomb.saga</groupId>
+        <artifactId>alpha-core</artifactId>
+        <version>0.0.3-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+        <groupId>io.servicecomb.saga</groupId>
+        <artifactId>pack-contract-thrift</artifactId>
+        <version>0.0.3-SNAPSHOT</version>
+      </dependency>
+      <dependency>
         <groupId>commons-io</groupId>
         <artifactId>commons-io</artifactId>
         <version>2.4</version>
@@ -268,6 +280,22 @@
         <artifactId>akka-slf4j_2.12</artifactId>
         <version>${akka.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.apache.thrift</groupId>
+        <artifactId>libthrift</artifactId>
+        <version>0.10.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.facebook.swift</groupId>
+        <artifactId>swift-service</artifactId>
+        <version>0.23.1</version>
+        <exclusions>
+          <exclusion>
+            <groupId>javax.validation</groupId>
+            <artifactId>validation-api</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
 
       <!-- test dependencies -->
       <dependency>
@@ -463,6 +491,18 @@
           <artifactId>maven-deploy-plugin</artifactId>
           <version>2.8.2</version>
         </plugin>
+        <plugin>
+          <groupId>com.facebook.mojo</groupId>
+          <artifactId>swift-maven-plugin</artifactId>
+          <version>0.23.1</version>
+          <executions>
+            <execution>
+              <goals>
+                <goal>generate</goal>
+              </goals>
+            </execution>
+          </executions>
+        </plugin>
       </plugins>
     </pluginManagement>
     <!-- enable the rat check by default -->

-- 
To stop receiving notification emails like this one, please contact
"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>.

[incubator-servicecomb-saga] 02/07: SCB-96 retrieve ids in header and put it into omega context

Posted by se...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

seanyinx pushed a commit to branch SCB-97_alpha_omega_bonding
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-saga.git

commit 1aa8564887c39e2afdef103a79eafe7a79929d1b
Author: Eric Lee <da...@huawei.com>
AuthorDate: Tue Dec 26 16:41:37 2017 +0800

    SCB-96 retrieve ids in header and put it into omega context
    
    Signed-off-by: Eric Lee <da...@huawei.com>
---
 .../saga/omega/transaction/TxEndedEvent.java       |   4 +-
 .../saga/omega/transaction/TxStartedEvent.java     |   4 +-
 .../TransactionHandlerInterceptor.java             |  39 +++----
 .../omega/transport/resttemplate/WebConfig.java    |  14 +--
 .../TransactionHandlerInterceptorTest.java         | 113 ++++-----------------
 5 files changed, 44 insertions(+), 130 deletions(-)

diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEndedEvent.java b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEndedEvent.java
index c24c1b3..6cc8f79 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEndedEvent.java
+++ b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxEndedEvent.java
@@ -17,8 +17,8 @@
 
 package io.servicecomb.saga.omega.transaction;
 
-public class TxEndedEvent extends TxEvent {
-  public TxEndedEvent(String globalTxId, String localTxId, String parentTxId) {
+class TxEndedEvent extends TxEvent {
+  TxEndedEvent(String globalTxId, String localTxId, String parentTxId) {
     super(globalTxId, localTxId, parentTxId);
   }
 }
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxStartedEvent.java b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxStartedEvent.java
index c278f54..830104f 100644
--- a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxStartedEvent.java
+++ b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TxStartedEvent.java
@@ -17,9 +17,9 @@
 
 package io.servicecomb.saga.omega.transaction;
 
-public class TxStartedEvent extends TxEvent {
+class TxStartedEvent extends TxEvent {
 
-  public TxStartedEvent(String globalTxId, String localTxId, String parentTxId, Object[] payloads) {
+  TxStartedEvent(String globalTxId, String localTxId, String parentTxId, Object[] payloads) {
     super(globalTxId, localTxId, parentTxId, payloads);
   }
 }
diff --git a/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptor.java b/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptor.java
index 56df07d..6363e4f 100644
--- a/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptor.java
+++ b/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptor.java
@@ -33,55 +33,42 @@ import org.slf4j.LoggerFactory;
 import org.springframework.web.servlet.HandlerInterceptor;
 import org.springframework.web.servlet.ModelAndView;
 
-import io.servicecomb.saga.omega.transaction.MessageSender;
-import io.servicecomb.saga.omega.transaction.MessageSerializer;
-import io.servicecomb.saga.omega.transaction.TxEndedEvent;
-import io.servicecomb.saga.omega.transaction.TxStartedEvent;
+import io.servicecomb.saga.omega.context.OmegaContext;
 
 public class TransactionHandlerInterceptor implements HandlerInterceptor {
 
   private static Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-  private final MessageSender sender;
+  private final OmegaContext omegaContext;
 
-  private final MessageSerializer serializer;
-
-  public TransactionHandlerInterceptor(MessageSender sender, MessageSerializer serializer) {
-    this.sender = sender;
-    this.serializer = serializer;
+  public TransactionHandlerInterceptor(OmegaContext omegaContext) {
+    this.omegaContext = omegaContext;
   }
 
   @Override
-  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
     String globalTxId = request.getHeader(GLOBAL_TX_ID_KEY);
     if (globalTxId == null) {
       LOG.info("no such header: {}", GLOBAL_TX_ID_KEY);
+    } else {
+      omegaContext.setGlobalTxId(globalTxId);
     }
-    String localTxId = request.getHeader(LOCAL_TX_ID_KEY);
-    if (localTxId == null) {
+    String parentTxId = request.getHeader(LOCAL_TX_ID_KEY);
+    if (parentTxId == null) {
       LOG.info("no such header: {}", LOCAL_TX_ID_KEY);
+    } else {
+      omegaContext.setParentTxId(parentTxId);
     }
-    // TODO: 12/25/2017 which content should be inside payloads?
-    sender.send(serializer.serialize(new TxStartedEvent(globalTxId, localTxId, null, null)));
     return true;
   }
 
   @Override
   public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
-      ModelAndView modelAndView) throws Exception {
+      ModelAndView modelAndView) {
   }
 
   @Override
   public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o,
-      Exception e) throws Exception {
-    String globalTxId = request.getHeader(GLOBAL_TX_ID_KEY);
-    if (globalTxId == null) {
-      LOG.info("no such header: {}", GLOBAL_TX_ID_KEY);
-    }
-    String localTxId = request.getHeader(LOCAL_TX_ID_KEY);
-    if (localTxId == null) {
-      LOG.info("no such header: {}", LOCAL_TX_ID_KEY);
-    }
-    sender.send(serializer.serialize(new TxEndedEvent(globalTxId, localTxId, null)));
+      Exception e) {
   }
 }
diff --git a/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/WebConfig.java b/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/WebConfig.java
index 7d4fe7f..7650d3c 100644
--- a/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/WebConfig.java
+++ b/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/WebConfig.java
@@ -26,25 +26,21 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc;
 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
 
-import io.servicecomb.saga.omega.transaction.MessageSender;
-import io.servicecomb.saga.omega.transaction.MessageSerializer;
+import io.servicecomb.saga.omega.context.OmegaContext;
 
 @Configuration
 @EnableWebMvc
 public class WebConfig extends WebMvcConfigurerAdapter {
 
-  private MessageSender sender;
-
-  private MessageSerializer serializer;
+  private final OmegaContext omegaContext;
 
   @Autowired
-  public WebConfig(MessageSender sender, MessageSerializer serializer) {
-    this.sender = sender;
-    this.serializer = serializer;
+  public WebConfig(OmegaContext omegaContext) {
+    this.omegaContext = omegaContext;
   }
 
   @Override
   public void addInterceptors(InterceptorRegistry registry) {
-    registry.addInterceptor(new TransactionHandlerInterceptor(sender, serializer));
+    registry.addInterceptor(new TransactionHandlerInterceptor(omegaContext));
   }
 }
diff --git a/omega/omega-transport/omega-transport-resttemplate/src/test/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptorTest.java b/omega/omega-transport/omega-transport-resttemplate/src/test/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptorTest.java
index 6d447f5..a6c29cb 100644
--- a/omega/omega-transport/omega-transport-resttemplate/src/test/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptorTest.java
+++ b/omega/omega-transport/omega-transport-resttemplate/src/test/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptorTest.java
@@ -21,132 +21,63 @@ package io.servicecomb.saga.omega.transport.resttemplate;
 import static io.servicecomb.saga.omega.transport.resttemplate.TransactionClientHttpRequestInterceptor.GLOBAL_TX_ID_KEY;
 import static io.servicecomb.saga.omega.transport.resttemplate.TransactionClientHttpRequestInterceptor.LOCAL_TX_ID_KEY;
 import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.nullValue;
 import static org.junit.Assert.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
 import java.util.UUID;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Import;
-import org.springframework.test.context.junit4.SpringRunner;
 import org.springframework.web.servlet.HandlerInterceptor;
 
-import io.servicecomb.saga.omega.transaction.MessageSender;
-import io.servicecomb.saga.omega.transaction.MessageSerializer;
-import io.servicecomb.saga.omega.transport.resttemplate.TransactionHandlerInterceptorTest.MessageConfig;
+import io.servicecomb.saga.omega.context.OmegaContext;
 
-@RunWith(SpringRunner.class)
-@Import({MessageConfig.class})
 public class TransactionHandlerInterceptorTest {
-  private static final String TX_STARTED_EVENT = "TxStartedEvent";
-  private static final String TX_ENDED_EVENT = "TxEndedEvent";
-  private static final String globalTxId = UUID.randomUUID().toString();
-  private static final String localTxId = UUID.randomUUID().toString();
 
-  @Autowired
-  private MessageSender sender;
+  private static final String globalTxId = UUID.randomUUID().toString();
 
-  @Autowired
-  private MessageSerializer serializer;
+  private static final String localTxId = UUID.randomUUID().toString();
 
-  @Autowired
-  private TransactionHandlerInterceptor requestInterceptor;
+  private final OmegaContext omegaContext = new OmegaContext();
 
-  @Autowired
-  private List<byte[]> messages;
+  private HandlerInterceptor requestInterceptor = new TransactionHandlerInterceptor(omegaContext);
 
   private HttpServletRequest request = mock(HttpServletRequest.class);
 
   private HttpServletResponse response = mock(HttpServletResponse.class);
 
-  @After
-  public void tearDown() throws Exception {
-    messages.clear();
+  @Before
+  public void setUp() {
+    omegaContext.setGlobalTxId(null);
+    omegaContext.setLocalTxId(null);
+    omegaContext.setParentTxId(null);
   }
 
   @Test
-  public void preInterceptHeaderValueAndSendOut() throws Exception {
+  public void setUpOmegaContextInTransactionRequest() throws Exception {
     when(request.getHeader(GLOBAL_TX_ID_KEY)).thenReturn(globalTxId);
     when(request.getHeader(LOCAL_TX_ID_KEY)).thenReturn(localTxId);
 
     requestInterceptor.preHandle(request, response, null);
 
-    assertThat(messages.size(), is(1));
-    String deserializedString = new String(messages.get(0));
-    assertThat(deserializedString.contains(TX_STARTED_EVENT), is(true));
-    assertThat(deserializedString.startsWith(globalTxId), is(true));
-    assertThat(deserializedString.contains(localTxId), is(true));
+    assertThat(omegaContext.globalTxId(), is(globalTxId));
+    assertThat(omegaContext.parentTxId(), is(localTxId));
   }
 
   @Test
-  public void postInterceptHeaderValueAndSendOut() throws Exception {
-    when(request.getHeader(GLOBAL_TX_ID_KEY)).thenReturn(globalTxId);
-    when(request.getHeader(LOCAL_TX_ID_KEY)).thenReturn(localTxId);
-
-    requestInterceptor.afterCompletion(request, response, null, null);
+  public void doNothingInNonTransactionRequest() throws Exception {
+    when(request.getHeader(GLOBAL_TX_ID_KEY)).thenReturn(null);
+    when(request.getHeader(LOCAL_TX_ID_KEY)).thenReturn(null);
 
-    assertThat(messages.size(), is(1));
-    String deserializedString = new String(messages.get(0));
-    assertThat(deserializedString.contains(TX_ENDED_EVENT), is(true));
-    assertThat(deserializedString.startsWith(globalTxId), is(true));
-    assertThat(deserializedString.contains(localTxId), is(true));
-  }
-
-  @Configuration
-  static class MessageConfig {
-    private final List<byte[]> messages = new ArrayList<>();
-
-    @Bean
-    List<byte[]> messages() {
-      return messages;
-    }
-
-    @Bean
-    MessageSender sender() {
-      return messages::add;
-    }
-
-    @Bean
-    MessageSerializer serializer() {
-      return event -> {
-        if (TX_STARTED_EVENT.equals(event.type())) {
-          return txStartedEvent(event.globalTxId(),
-              event.localTxId(),
-              event.parentTxId(),
-              event.payloads()).getBytes();
-        }
-        return txEndedEvent(event.globalTxId(),
-            event.localTxId(),
-            event.parentTxId()).getBytes();
-      };
-    }
-
-    @Bean
-    HandlerInterceptor handlerInterceptor(MessageSender sender, MessageSerializer serializer) {
-      return new TransactionHandlerInterceptor(sender, serializer);
-    }
-  }
-
-  private static String txStartedEvent(String globalTxId,
-      String localTxId,
-      String parentTxId,
-      Object[] payloads) {
-    return globalTxId + ":" + localTxId + ":" + parentTxId + ":" + TX_STARTED_EVENT + ":" + Arrays.toString(payloads);
-  }
+    requestInterceptor.preHandle(request, response, null);
 
-  private static String txEndedEvent(String globalTxId, String localTxId, String parentTxId) {
-    return globalTxId + ":" + localTxId + ":" + parentTxId + ":" + TX_ENDED_EVENT;
+    assertThat(omegaContext.globalTxId(), is(nullValue()));
+    assertThat(omegaContext.parentTxId(), is(nullValue()));
+    assertThat(omegaContext.localTxId(), is(nullValue()));
   }
 }
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>.

[incubator-servicecomb-saga] 04/07: SCB-97 removed unnecessary dependency on serializer

Posted by se...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

seanyinx pushed a commit to branch SCB-97_alpha_omega_bonding
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-saga.git

commit a02a62cd03613227a978c96f8fc15eb8959590c4
Author: seanyinx <se...@huawei.com>
AuthorDate: Tue Dec 26 09:09:17 2017 +0800

    SCB-97 removed unnecessary dependency on serializer
    
    Signed-off-by: seanyinx <se...@huawei.com>
---
 .../spring/TransactionInterceptionTest.java        | 31 ++++++++++------------
 .../PostTransactionInterceptorTest.java            |  3 +--
 .../transaction/PreTransactionInterceptorTest.java | 13 ++++-----
 3 files changed, 20 insertions(+), 27 deletions(-)

diff --git a/omega/omega-spring-tx/src/test/java/io/servicecomb/saga/omega/transaction/spring/TransactionInterceptionTest.java b/omega/omega-spring-tx/src/test/java/io/servicecomb/saga/omega/transaction/spring/TransactionInterceptionTest.java
index 2ba1785..5aefb68 100644
--- a/omega/omega-spring-tx/src/test/java/io/servicecomb/saga/omega/transaction/spring/TransactionInterceptionTest.java
+++ b/omega/omega-spring-tx/src/test/java/io/servicecomb/saga/omega/transaction/spring/TransactionInterceptionTest.java
@@ -43,7 +43,7 @@ import org.springframework.test.context.junit4.SpringRunner;
 import io.servicecomb.saga.omega.context.OmegaContext;
 import io.servicecomb.saga.omega.transaction.MessageHandler;
 import io.servicecomb.saga.omega.transaction.MessageSender;
-import io.servicecomb.saga.omega.transaction.MessageSerializer;
+import io.servicecomb.saga.omega.transaction.TxEvent;
 import io.servicecomb.saga.omega.transaction.spring.TransactionInterceptionTest.MessageConfig;
 
 @RunWith(SpringRunner.class)
@@ -128,25 +128,22 @@ public class TransactionInterceptionTest {
     }
 
     @Bean
-    MessageSender sender(MessageSerializer serializer) {
-      return (event) -> messages.add(serializer.serialize(event));
+    MessageSender sender() {
+      return (event) -> messages.add(serialize(event));
     }
 
-    @Bean
-    MessageSerializer serializer() {
-      return event -> {
-        if (TX_STARTED_EVENT.equals(event.type())) {
-          User user = ((User) event.payloads()[0]);
-          return txStartedEvent(event.globalTxId(),
-              event.localTxId(),
-              event.parentTxId(),
-              user.username(),
-              user.email()).getBytes();
-        }
-        return txEndedEvent(event.globalTxId(),
+    private byte[] serialize(TxEvent event) {
+      if (TX_STARTED_EVENT.equals(event.type())) {
+        User user = ((User) event.payloads()[0]);
+        return txStartedEvent(event.globalTxId(),
             event.localTxId(),
-            event.parentTxId()).getBytes();
-      };
+            event.parentTxId(),
+            user.username(),
+            user.email()).getBytes();
+      }
+      return txEndedEvent(event.globalTxId(),
+          event.localTxId(),
+          event.parentTxId()).getBytes();
     }
 
     @Bean
diff --git a/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/PostTransactionInterceptorTest.java b/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/PostTransactionInterceptorTest.java
index 508c987..7c72513 100644
--- a/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/PostTransactionInterceptorTest.java
+++ b/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/PostTransactionInterceptorTest.java
@@ -32,8 +32,7 @@ public class PostTransactionInterceptorTest {
   private final String localTxId = UUID.randomUUID().toString();
   private final String parentTxId = UUID.randomUUID().toString();
 
-  private final MessageSerializer serializer = event -> serialize(globalTxId, localTxId, parentTxId);
-  private final MessageSender sender = (msg) -> messages.add(serializer.serialize(msg));
+  private final MessageSender sender = (msg) -> messages.add(serialize(msg.globalTxId(), msg.localTxId(), msg.parentTxId()));
 
   private final PostTransactionInterceptor interceptor = new PostTransactionInterceptor(sender);
 
diff --git a/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/PreTransactionInterceptorTest.java b/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/PreTransactionInterceptorTest.java
index 0fcf64e..db6a53d 100644
--- a/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/PreTransactionInterceptorTest.java
+++ b/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/PreTransactionInterceptorTest.java
@@ -33,14 +33,11 @@ public class PreTransactionInterceptorTest {
   private final String localTxId = UUID.randomUUID().toString();
   private final String parentTxId = UUID.randomUUID().toString();
 
-  private final MessageSerializer serializer = event -> {
-    if (event.payloads()[0] instanceof String) {
-      String message = (String) event.payloads()[0];
-      return serialize(globalTxId, localTxId, parentTxId, message);
-    }
-    throw new IllegalArgumentException("Expected instance of String, but was " + event.getClass());
-  };
-  private final MessageSender sender = (msg) -> messages.add(serializer.serialize(msg));
+  private final MessageSender sender = (msg) -> messages.add(
+      serialize(msg.globalTxId(),
+          msg.localTxId(),
+          msg.parentTxId(),
+          (String) msg.payloads()[0]));
 
   private final String message = uniquify("message");
   private final PreTransactionInterceptor interceptor = new PreTransactionInterceptor(sender);

-- 
To stop receiving notification emails like this one, please contact
"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>.

[incubator-servicecomb-saga] 07/07: SCB-97 glued request interception with transaction aop

Posted by se...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

seanyinx pushed a commit to branch SCB-97_alpha_omega_bonding
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-saga.git

commit 9bd3b665524ef4b798f1cad4e411772a0c5a09d6
Author: seanyinx <se...@huawei.com>
AuthorDate: Tue Dec 26 18:37:52 2017 +0800

    SCB-97 glued request interception with transaction aop
    
    Signed-off-by: seanyinx <se...@huawei.com>
---
 integration-tests/pack-tests/pom.xml                 | 10 +++++++---
 .../integration/pack/tests/GreetingController.java   | 12 +-----------
 .../saga/integration/pack/tests/PackIT.java          | 18 ++++++++++++++++--
 .../servicecomb/saga/omega/context/OmegaContext.java | 20 ++++++++++++++++++++
 .../saga/omega/context}/UniqueIdGenerator.java       |  5 +----
 .../saga/omega/context/OmegaContextTest.java         |  2 +-
 omega/omega-spring-starter/pom.xml                   |  4 ----
 .../saga/omega/spring/OmegaSpringConfig.java         | 13 +++++++++++++
 .../transaction/spring/TransactionAspectConfig.java  |  4 ----
 .../spring/TransactionInterceptionTest.java          |  6 ++++++
 .../transport/resttemplate/RestTemplateConfig.java   | 10 ++--------
 .../TransactionClientHttpRequestInterceptor.java     | 19 +++++++------------
 .../resttemplate/TransactionHandlerInterceptor.java  | 18 +++++++-----------
 .../src/main/resources/META-INF/spring.factories     | 19 +++++++++++++++++++
 .../TransactionClientHttpRequestInterceptorTest.java | 10 +++++-----
 .../TransactionHandlerInterceptorTest.java           |  8 +++++---
 .../resttemplate/UniqueIdGeneratorTest.java          |  2 ++
 17 files changed, 112 insertions(+), 68 deletions(-)

diff --git a/integration-tests/pack-tests/pom.xml b/integration-tests/pack-tests/pom.xml
index bc7717c..41a40d8 100644
--- a/integration-tests/pack-tests/pom.xml
+++ b/integration-tests/pack-tests/pom.xml
@@ -46,6 +46,10 @@
       <artifactId>omega-spring-starter</artifactId>
     </dependency>
     <dependency>
+      <groupId>io.servicecomb.saga</groupId>
+      <artifactId>omega-transport-resttemplate</artifactId>
+    </dependency>
+    <dependency>
       <groupId>commons-logging</groupId>
       <artifactId>commons-logging</artifactId>
       <version>1.2</version>
@@ -193,9 +197,9 @@
             <version>${maven.failsafe.version}</version>
             <configuration>
               <systemPropertyVariables>
-                <saga.address>
-                  http://${docker.hostname}:${alpha.port}
-                </saga.address>
+                <alpha.cluster.address>
+                  ${docker.hostname}:${alpha.port}
+                </alpha.cluster.address>
               </systemPropertyVariables>
               <argLine>${jacoco.failsafe.argLine}</argLine>
             </configuration>
diff --git a/integration-tests/pack-tests/src/test/java/io/servicecomb/saga/integration/pack/tests/GreetingController.java b/integration-tests/pack-tests/src/test/java/io/servicecomb/saga/integration/pack/tests/GreetingController.java
index 11aa0e8..1a6d489 100644
--- a/integration-tests/pack-tests/src/test/java/io/servicecomb/saga/integration/pack/tests/GreetingController.java
+++ b/integration-tests/pack-tests/src/test/java/io/servicecomb/saga/integration/pack/tests/GreetingController.java
@@ -17,8 +17,6 @@
 
 package io.servicecomb.saga.integration.pack.tests;
 
-import java.util.UUID;
-
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Controller;
@@ -26,27 +24,19 @@ import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 
-import io.servicecomb.saga.omega.context.OmegaContext;
-
 @Controller
 @RequestMapping("/")
 public class GreetingController {
   private final GreetingService greetingService;
-  private final OmegaContext context;
 
   @Autowired
-  public GreetingController(GreetingService greetingService, OmegaContext context) {
+  public GreetingController(GreetingService greetingService) {
     this.greetingService = greetingService;
-    this.context = context;
   }
 
 
   @GetMapping("/greet")
   ResponseEntity<String> greet(@RequestParam String name) {
-    // TODO: 2017/12/26 to be removed when tx id retrieval is done
-    context.setGlobalTxId(UUID.randomUUID().toString());
-    context.setLocalTxId(UUID.randomUUID().toString());
-
     return ResponseEntity.ok(greetingService.greet(name));
   }
 }
diff --git a/integration-tests/pack-tests/src/test/java/io/servicecomb/saga/integration/pack/tests/PackIT.java b/integration-tests/pack-tests/src/test/java/io/servicecomb/saga/integration/pack/tests/PackIT.java
index ad6bed1..3c1d0eb 100644
--- a/integration-tests/pack-tests/src/test/java/io/servicecomb/saga/integration/pack/tests/PackIT.java
+++ b/integration-tests/pack-tests/src/test/java/io/servicecomb/saga/integration/pack/tests/PackIT.java
@@ -17,23 +17,29 @@
 
 package io.servicecomb.saga.integration.pack.tests;
 
+import static io.servicecomb.saga.omega.context.OmegaContext.GLOBAL_TX_ID_KEY;
 import static org.hamcrest.core.Is.is;
 import static org.junit.Assert.assertThat;
+import static org.springframework.http.HttpMethod.GET;
 import static org.springframework.http.HttpStatus.OK;
 
+import java.util.UUID;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
 import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
 import org.springframework.http.ResponseEntity;
 import org.springframework.test.context.junit4.SpringRunner;
 
 import io.servicecomb.saga.omega.context.OmegaContext;
 
 @RunWith(SpringRunner.class)
-@SpringBootTest(classes = GreetingApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT, properties = {"alpha.cluster.address=localhost:32782"})
+@SpringBootTest(classes = GreetingApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
 public class PackIT {
   @Autowired
   private TestRestTemplate restTemplate;
@@ -44,7 +50,15 @@ public class PackIT {
 
   @Test
   public void updatesTxStateToAlpha() throws Exception {
-    ResponseEntity<String> entity = restTemplate.getForEntity("/greet?name={name}", String.class, "mike");
+    HttpHeaders headers = new HttpHeaders();
+
+    headers.set(GLOBAL_TX_ID_KEY, UUID.randomUUID().toString());
+
+    ResponseEntity<String> entity = restTemplate.exchange("/greet?name={name}",
+        GET,
+        new HttpEntity<>(headers),
+        String.class,
+        "mike");
 
     assertThat(entity.getStatusCode(), is(OK));
     assertThat(entity.getBody(), is("Greetings, mike"));
diff --git a/omega/omega-context/src/main/java/io/servicecomb/saga/omega/context/OmegaContext.java b/omega/omega-context/src/main/java/io/servicecomb/saga/omega/context/OmegaContext.java
index 17c6246..d8cca65 100644
--- a/omega/omega-context/src/main/java/io/servicecomb/saga/omega/context/OmegaContext.java
+++ b/omega/omega-context/src/main/java/io/servicecomb/saga/omega/context/OmegaContext.java
@@ -23,10 +23,24 @@ import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
 public class OmegaContext {
+  public static final String GLOBAL_TX_ID_KEY = "X-Pack-Global-Transaction-Id";
+  public static final String LOCAL_TX_ID_KEY = "X-Pack-Local-Transaction-Id";
+
   private final ThreadLocal<String> globalTxId = new ThreadLocal<>();
   private final ThreadLocal<String> localTxId = new ThreadLocal<>();
   private final ThreadLocal<String> parentTxId = new ThreadLocal<>();
   private final Map<String, CompensationContext> compensationContexts = new ConcurrentHashMap<>();
+  private final IdGenerator<String> idGenerator;
+
+  public OmegaContext(IdGenerator<String> idGenerator) {
+    this.idGenerator = idGenerator;
+  }
+
+  public String newGlobalTxId() {
+    String id = idGenerator.nextId();
+    globalTxId.set(id);
+    return id;
+  }
 
   public void setGlobalTxId(String txId) {
     globalTxId.set(txId);
@@ -36,6 +50,12 @@ public class OmegaContext {
     return globalTxId.get();
   }
 
+  public String newLocalTxId() {
+    String id = idGenerator.nextId();
+    localTxId.set(id);
+    return id;
+  }
+
   public void setLocalTxId(String localTxId) {
     this.localTxId.set(localTxId);
   }
diff --git a/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/UniqueIdGenerator.java b/omega/omega-context/src/main/java/io/servicecomb/saga/omega/context/UniqueIdGenerator.java
similarity index 89%
rename from omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/UniqueIdGenerator.java
rename to omega/omega-context/src/main/java/io/servicecomb/saga/omega/context/UniqueIdGenerator.java
index 8cb3eb1..300b522 100644
--- a/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/UniqueIdGenerator.java
+++ b/omega/omega-context/src/main/java/io/servicecomb/saga/omega/context/UniqueIdGenerator.java
@@ -13,15 +13,12 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
- *
  */
 
-package io.servicecomb.saga.omega.transport.resttemplate;
+package io.servicecomb.saga.omega.context;
 
 import java.util.UUID;
 
-import io.servicecomb.saga.omega.context.IdGenerator;
-
 public class UniqueIdGenerator implements IdGenerator<String> {
   @Override
   public String nextId() {
diff --git a/omega/omega-context/src/test/java/io/servicecomb/saga/omega/context/OmegaContextTest.java b/omega/omega-context/src/test/java/io/servicecomb/saga/omega/context/OmegaContextTest.java
index e890c18..752f0b8 100644
--- a/omega/omega-context/src/test/java/io/servicecomb/saga/omega/context/OmegaContextTest.java
+++ b/omega/omega-context/src/test/java/io/servicecomb/saga/omega/context/OmegaContextTest.java
@@ -29,7 +29,7 @@ import org.junit.Test;
 
 public class OmegaContextTest {
 
-  private final OmegaContext omegaContext = new OmegaContext();
+  private final OmegaContext omegaContext = new OmegaContext(() -> "ignored");
 
   @Test
   public void eachThreadGetsDifferentGlobalTxId() throws Exception {
diff --git a/omega/omega-spring-starter/pom.xml b/omega/omega-spring-starter/pom.xml
index b900a47..59b81f8 100644
--- a/omega/omega-spring-starter/pom.xml
+++ b/omega/omega-spring-starter/pom.xml
@@ -31,10 +31,6 @@
   <dependencies>
     <dependency>
       <groupId>io.servicecomb.saga</groupId>
-      <artifactId>omega-transport-resttemplate</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.servicecomb.saga</groupId>
       <artifactId>omega-spring-tx</artifactId>
     </dependency>
     <dependency>
diff --git a/omega/omega-spring-starter/src/main/java/io/servicecomb/saga/omega/spring/OmegaSpringConfig.java b/omega/omega-spring-starter/src/main/java/io/servicecomb/saga/omega/spring/OmegaSpringConfig.java
index ae92123..33a0cbc 100644
--- a/omega/omega-spring-starter/src/main/java/io/servicecomb/saga/omega/spring/OmegaSpringConfig.java
+++ b/omega/omega-spring-starter/src/main/java/io/servicecomb/saga/omega/spring/OmegaSpringConfig.java
@@ -27,6 +27,9 @@ import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
 import io.servicecomb.saga.omega.connector.thrift.ThriftMessageSender;
+import io.servicecomb.saga.omega.context.IdGenerator;
+import io.servicecomb.saga.omega.context.OmegaContext;
+import io.servicecomb.saga.omega.context.UniqueIdGenerator;
 import io.servicecomb.saga.omega.format.NativeMessageFormat;
 import io.servicecomb.saga.omega.transaction.MessageSender;
 
@@ -35,6 +38,16 @@ class OmegaSpringConfig {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   @Bean
+  IdGenerator<String> idGenerator() {
+    return new UniqueIdGenerator();
+  }
+
+  @Bean
+  OmegaContext omegaContext(IdGenerator<String> idGenerator) {
+    return new OmegaContext(idGenerator);
+  }
+
+  @Bean
   MessageSender messageSender(@Value("${alpha.cluster.address}") String[] addresses) {
     // TODO: 2017/12/26 connect to the one with lowest latency
     for (String address : addresses) {
diff --git a/omega/omega-spring-tx/src/main/java/io/servicecomb/saga/omega/transaction/spring/TransactionAspectConfig.java b/omega/omega-spring-tx/src/main/java/io/servicecomb/saga/omega/transaction/spring/TransactionAspectConfig.java
index 59f7d2e..358ef26 100644
--- a/omega/omega-spring-tx/src/main/java/io/servicecomb/saga/omega/transaction/spring/TransactionAspectConfig.java
+++ b/omega/omega-spring-tx/src/main/java/io/servicecomb/saga/omega/transaction/spring/TransactionAspectConfig.java
@@ -28,10 +28,6 @@ import io.servicecomb.saga.omega.transaction.TransactionAspect;
 @Configuration
 @EnableAspectJAutoProxy
 public class TransactionAspectConfig {
-  @Bean
-  OmegaContext omegaContext() {
-    return new OmegaContext();
-  }
 
   @Bean
   TransactionAspect transactionAspect(MessageSender sender, OmegaContext context) {
diff --git a/omega/omega-spring-tx/src/test/java/io/servicecomb/saga/omega/transaction/spring/TransactionInterceptionTest.java b/omega/omega-spring-tx/src/test/java/io/servicecomb/saga/omega/transaction/spring/TransactionInterceptionTest.java
index 5aefb68..67fdff9 100644
--- a/omega/omega-spring-tx/src/test/java/io/servicecomb/saga/omega/transaction/spring/TransactionInterceptionTest.java
+++ b/omega/omega-spring-tx/src/test/java/io/servicecomb/saga/omega/transaction/spring/TransactionInterceptionTest.java
@@ -41,6 +41,7 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.test.context.junit4.SpringRunner;
 
 import io.servicecomb.saga.omega.context.OmegaContext;
+import io.servicecomb.saga.omega.context.UniqueIdGenerator;
 import io.servicecomb.saga.omega.transaction.MessageHandler;
 import io.servicecomb.saga.omega.transaction.MessageSender;
 import io.servicecomb.saga.omega.transaction.TxEvent;
@@ -123,6 +124,11 @@ public class TransactionInterceptionTest {
     private final List<byte[]> messages = new ArrayList<>();
 
     @Bean
+    OmegaContext omegaContext() {
+      return new OmegaContext(new UniqueIdGenerator());
+    }
+
+    @Bean
     List<byte[]> messages() {
       return messages;
     }
diff --git a/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/RestTemplateConfig.java b/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/RestTemplateConfig.java
index 34683b1..053e3ff 100644
--- a/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/RestTemplateConfig.java
+++ b/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/RestTemplateConfig.java
@@ -25,22 +25,16 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.http.client.ClientHttpRequestInterceptor;
 import org.springframework.web.client.RestTemplate;
 
-import io.servicecomb.saga.omega.context.IdGenerator;
 import io.servicecomb.saga.omega.context.OmegaContext;
 
 @Configuration
 public class RestTemplateConfig {
 
   @Bean
-  IdGenerator<String> idGenerator() {
-    return new UniqueIdGenerator();
-  }
-
-  @Bean
-  public RestTemplate restTemplate(IdGenerator<String> idGenerator, OmegaContext context) {
+  public RestTemplate restTemplate(OmegaContext context) {
     RestTemplate template = new RestTemplate();
     List<ClientHttpRequestInterceptor> interceptors = template.getInterceptors();
-    interceptors.add(new TransactionClientHttpRequestInterceptor(context, idGenerator));
+    interceptors.add(new TransactionClientHttpRequestInterceptor(context));
     template.setInterceptors(interceptors);
     return template;
   }
diff --git a/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionClientHttpRequestInterceptor.java b/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionClientHttpRequestInterceptor.java
index 158fbc8..35bc9d0 100644
--- a/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionClientHttpRequestInterceptor.java
+++ b/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionClientHttpRequestInterceptor.java
@@ -18,6 +18,9 @@
 
 package io.servicecomb.saga.omega.transport.resttemplate;
 
+import static io.servicecomb.saga.omega.context.OmegaContext.GLOBAL_TX_ID_KEY;
+import static io.servicecomb.saga.omega.context.OmegaContext.LOCAL_TX_ID_KEY;
+
 import java.io.IOException;
 
 import org.springframework.http.HttpRequest;
@@ -25,20 +28,14 @@ import org.springframework.http.client.ClientHttpRequestExecution;
 import org.springframework.http.client.ClientHttpRequestInterceptor;
 import org.springframework.http.client.ClientHttpResponse;
 
-import io.servicecomb.saga.omega.context.IdGenerator;
 import io.servicecomb.saga.omega.context.OmegaContext;
 
-public class TransactionClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
-
-  public static final String GLOBAL_TX_ID_KEY = "X-Pack-Global-Transaction-Id";
-  public static final String LOCAL_TX_ID_KEY = "X-Pack-Local-Transaction-Id";
+class TransactionClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
 
   private final OmegaContext omegaContext;
-  private final IdGenerator<String> idGenerator;
 
-  TransactionClientHttpRequestInterceptor(OmegaContext omegaContext, IdGenerator<String> idGenerator) {
+  TransactionClientHttpRequestInterceptor(OmegaContext omegaContext) {
     this.omegaContext = omegaContext;
-    this.idGenerator = idGenerator;
   }
 
   @Override
@@ -54,8 +51,7 @@ public class TransactionClientHttpRequestInterceptor implements ClientHttpReques
     String globalTxId = omegaContext.globalTxId();
 
     if (globalTxId == null) {
-      globalTxId = idGenerator.nextId();
-      omegaContext.setGlobalTxId(globalTxId);
+      return omegaContext.newGlobalTxId();
     }
     return globalTxId;
   }
@@ -64,8 +60,7 @@ public class TransactionClientHttpRequestInterceptor implements ClientHttpReques
     String localTxId = omegaContext.localTxId();
 
     if (localTxId == null) {
-      localTxId = idGenerator.nextId();
-      omegaContext.setLocalTxId(localTxId);
+      return omegaContext.newLocalTxId();
     }
     return localTxId;
   }
diff --git a/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptor.java b/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptor.java
index 6363e4f..d71c558 100644
--- a/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptor.java
+++ b/omega/omega-transport/omega-transport-resttemplate/src/main/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptor.java
@@ -20,8 +20,8 @@
 
 package io.servicecomb.saga.omega.transport.resttemplate;
 
-import static io.servicecomb.saga.omega.transport.resttemplate.TransactionClientHttpRequestInterceptor.GLOBAL_TX_ID_KEY;
-import static io.servicecomb.saga.omega.transport.resttemplate.TransactionClientHttpRequestInterceptor.LOCAL_TX_ID_KEY;
+import static io.servicecomb.saga.omega.context.OmegaContext.GLOBAL_TX_ID_KEY;
+import static io.servicecomb.saga.omega.context.OmegaContext.LOCAL_TX_ID_KEY;
 
 import java.lang.invoke.MethodHandles;
 
@@ -35,13 +35,13 @@ import org.springframework.web.servlet.ModelAndView;
 
 import io.servicecomb.saga.omega.context.OmegaContext;
 
-public class TransactionHandlerInterceptor implements HandlerInterceptor {
+class TransactionHandlerInterceptor implements HandlerInterceptor {
 
   private static Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   private final OmegaContext omegaContext;
 
-  public TransactionHandlerInterceptor(OmegaContext omegaContext) {
+  TransactionHandlerInterceptor(OmegaContext omegaContext) {
     this.omegaContext = omegaContext;
   }
 
@@ -49,15 +49,11 @@ public class TransactionHandlerInterceptor implements HandlerInterceptor {
   public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
     String globalTxId = request.getHeader(GLOBAL_TX_ID_KEY);
     if (globalTxId == null) {
-      LOG.info("no such header: {}", GLOBAL_TX_ID_KEY);
+      LOG.debug("no such header: {}", GLOBAL_TX_ID_KEY);
     } else {
       omegaContext.setGlobalTxId(globalTxId);
-    }
-    String parentTxId = request.getHeader(LOCAL_TX_ID_KEY);
-    if (parentTxId == null) {
-      LOG.info("no such header: {}", LOCAL_TX_ID_KEY);
-    } else {
-      omegaContext.setParentTxId(parentTxId);
+      omegaContext.newLocalTxId();
+      omegaContext.setParentTxId(request.getHeader(LOCAL_TX_ID_KEY));
     }
     return true;
   }
diff --git a/omega/omega-transport/omega-transport-resttemplate/src/main/resources/META-INF/spring.factories b/omega/omega-transport/omega-transport-resttemplate/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000..7d03c78
--- /dev/null
+++ b/omega/omega-transport/omega-transport-resttemplate/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements.  See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License.  You may obtain a copy of the License at
+##
+##      http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+  io.servicecomb.saga.omega.transport.resttemplate.WebConfig,\
+  io.servicecomb.saga.omega.transport.resttemplate.RestTemplateConfig
diff --git a/omega/omega-transport/omega-transport-resttemplate/src/test/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionClientHttpRequestInterceptorTest.java b/omega/omega-transport/omega-transport-resttemplate/src/test/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionClientHttpRequestInterceptorTest.java
index 41da9ec..223b56c 100644
--- a/omega/omega-transport/omega-transport-resttemplate/src/test/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionClientHttpRequestInterceptorTest.java
+++ b/omega/omega-transport/omega-transport-resttemplate/src/test/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionClientHttpRequestInterceptorTest.java
@@ -19,8 +19,8 @@
 package io.servicecomb.saga.omega.transport.resttemplate;
 
 import static com.seanyinx.github.unit.scaffolding.Randomness.uniquify;
-import static io.servicecomb.saga.omega.transport.resttemplate.TransactionClientHttpRequestInterceptor.GLOBAL_TX_ID_KEY;
-import static io.servicecomb.saga.omega.transport.resttemplate.TransactionClientHttpRequestInterceptor.LOCAL_TX_ID_KEY;
+import static io.servicecomb.saga.omega.context.OmegaContext.GLOBAL_TX_ID_KEY;
+import static io.servicecomb.saga.omega.context.OmegaContext.LOCAL_TX_ID_KEY;
 import static org.hamcrest.Matchers.contains;
 import static org.hamcrest.core.Is.is;
 import static org.junit.Assert.assertThat;
@@ -57,10 +57,10 @@ public class TransactionClientHttpRequestInterceptorTest {
   private final String localTxId = uniquify("local tx id");
   private final IdGenerator<String> idGenerator = Mockito.mock(IdGenerator.class);
 
-  private final OmegaContext omegaContext = new OmegaContext();
+  private final OmegaContext omegaContext = new OmegaContext(idGenerator);
   private final ClientHttpRequestInterceptor clientHttpRequestInterceptor = new TransactionClientHttpRequestInterceptor(
-      omegaContext,
-      idGenerator);
+      omegaContext
+  );
 
   @Before
   public void setUp() throws Exception {
diff --git a/omega/omega-transport/omega-transport-resttemplate/src/test/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptorTest.java b/omega/omega-transport/omega-transport-resttemplate/src/test/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptorTest.java
index a6c29cb..4aabddd 100644
--- a/omega/omega-transport/omega-transport-resttemplate/src/test/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptorTest.java
+++ b/omega/omega-transport/omega-transport-resttemplate/src/test/java/io/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptorTest.java
@@ -18,9 +18,10 @@
 
 package io.servicecomb.saga.omega.transport.resttemplate;
 
-import static io.servicecomb.saga.omega.transport.resttemplate.TransactionClientHttpRequestInterceptor.GLOBAL_TX_ID_KEY;
-import static io.servicecomb.saga.omega.transport.resttemplate.TransactionClientHttpRequestInterceptor.LOCAL_TX_ID_KEY;
+import static io.servicecomb.saga.omega.context.OmegaContext.GLOBAL_TX_ID_KEY;
+import static io.servicecomb.saga.omega.context.OmegaContext.LOCAL_TX_ID_KEY;
 import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
 import static org.hamcrest.Matchers.nullValue;
 import static org.junit.Assert.assertThat;
 import static org.mockito.Mockito.mock;
@@ -43,7 +44,7 @@ public class TransactionHandlerInterceptorTest {
 
   private static final String localTxId = UUID.randomUUID().toString();
 
-  private final OmegaContext omegaContext = new OmegaContext();
+  private final OmegaContext omegaContext = new OmegaContext(() -> "ignored");
 
   private HandlerInterceptor requestInterceptor = new TransactionHandlerInterceptor(omegaContext);
 
@@ -66,6 +67,7 @@ public class TransactionHandlerInterceptorTest {
     requestInterceptor.preHandle(request, response, null);
 
     assertThat(omegaContext.globalTxId(), is(globalTxId));
+    assertThat(omegaContext.localTxId(), is(notNullValue()));
     assertThat(omegaContext.parentTxId(), is(localTxId));
   }
 
diff --git a/omega/omega-transport/omega-transport-resttemplate/src/test/java/io/servicecomb/saga/omega/transport/resttemplate/UniqueIdGeneratorTest.java b/omega/omega-transport/omega-transport-resttemplate/src/test/java/io/servicecomb/saga/omega/transport/resttemplate/UniqueIdGeneratorTest.java
index 87338ea..720eb0b 100644
--- a/omega/omega-transport/omega-transport-resttemplate/src/test/java/io/servicecomb/saga/omega/transport/resttemplate/UniqueIdGeneratorTest.java
+++ b/omega/omega-transport/omega-transport-resttemplate/src/test/java/io/servicecomb/saga/omega/transport/resttemplate/UniqueIdGeneratorTest.java
@@ -34,6 +34,8 @@ import java.util.concurrent.Future;
 
 import org.junit.Test;
 
+import io.servicecomb.saga.omega.context.UniqueIdGenerator;
+
 public class UniqueIdGeneratorTest {
 
   private final UniqueIdGenerator idGenerator = new UniqueIdGenerator();

-- 
To stop receiving notification emails like this one, please contact
"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>.