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:21 UTC

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

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>.