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

[incubator-servicecomb-saga] 02/14: SCB-96 sent serialized message pre transactional

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

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

commit de1479a6e0e6d352e4e24ca2cb45b97207485146
Author: seanyinx <se...@huawei.com>
AuthorDate: Fri Dec 22 16:13:56 2017 +0800

    SCB-96 sent serialized message pre transactional
    
    Signed-off-by: seanyinx <se...@huawei.com>
---
 omega/omega-transaction/pom.xml                    | 35 ++++++++-
 .../saga/omega/transaction/MessageSender.java      | 22 ++++++
 .../saga/omega/transaction/MessageSerializer.java  | 22 ++++++
 .../transaction/PreTransactionInterceptor.java     | 32 +++++++++
 .../saga/omega/transaction/TransactionAspect.java  | 48 +++++++++++++
 .../omega/transaction/TransactionAspectConfig.java | 32 +++++++++
 .../transaction/PreTransactionInterceptorTest.java | 49 +++++++++++++
 .../transaction/TransactionInterceptionTest.java   | 82 ++++++++++++++++++++++
 .../omega/transaction/TransactionTestMain.java     | 28 ++++++++
 .../transaction/TransactionalUserService.java      | 38 ++++++++++
 .../servicecomb/saga/omega/transaction/User.java   | 49 +++++++++++++
 .../saga/omega/transaction/UserRepository.java     | 23 ++++++
 12 files changed, 459 insertions(+), 1 deletion(-)

diff --git a/omega/omega-transaction/pom.xml b/omega/omega-transaction/pom.xml
index b47e073..569e07f 100644
--- a/omega/omega-transaction/pom.xml
+++ b/omega/omega-transaction/pom.xml
@@ -31,8 +31,41 @@
   <dependencies>
     <dependency>
       <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot-starter-jdbc</artifactId>
+      <artifactId>spring-boot-starter</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-data-jpa</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.github.seanyinx</groupId>
+      <artifactId>unit-scaffolding</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>
 
 </project>
\ No newline at end of file
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
new file mode 100644
index 0000000..ab7bbaa
--- /dev/null
+++ b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSender.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.servicecomb.saga.omega.transaction;
+
+public interface MessageSender {
+  void send(byte[] message);
+}
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSerializer.java b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSerializer.java
new file mode 100644
index 0000000..1a88f13
--- /dev/null
+++ b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/MessageSerializer.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.servicecomb.saga.omega.transaction;
+
+public interface MessageSerializer {
+  byte[] serialize(Object[] message);
+}
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
new file mode 100644
index 0000000..089ba32
--- /dev/null
+++ b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/PreTransactionInterceptor.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transaction;
+
+class PreTransactionInterceptor {
+  private final MessageSender sender;
+  private final MessageSerializer serializer;
+
+  PreTransactionInterceptor(MessageSender sender, MessageSerializer serializer) {
+    this.sender = sender;
+    this.serializer = serializer;
+  }
+
+  void intercept(Object... message) {
+    sender.send(serializer.serialize(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
new file mode 100644
index 0000000..00f283a
--- /dev/null
+++ b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TransactionAspect.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transaction;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.Method;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Aspect
+class TransactionAspect {
+  private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+  private final PreTransactionInterceptor preTransactionInterceptor;
+
+
+  TransactionAspect(MessageSerializer serializer, MessageSender sender) {
+    this.preTransactionInterceptor = new PreTransactionInterceptor(sender, serializer);
+  }
+
+  @Around("execution(@javax.transaction.Transactional * *(..))")
+  Object advise(ProceedingJoinPoint joinPoint) throws Throwable {
+    Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
+    LOG.debug("Intercepting transactional method {}", method.toString());
+
+    preTransactionInterceptor.intercept(joinPoint.getArgs());
+    return joinPoint.proceed();
+  }
+}
diff --git a/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TransactionAspectConfig.java b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TransactionAspectConfig.java
new file mode 100644
index 0000000..5a9cd5e
--- /dev/null
+++ b/omega/omega-transaction/src/main/java/io/servicecomb/saga/omega/transaction/TransactionAspectConfig.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transaction;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+
+@Configuration
+@EnableAspectJAutoProxy
+class TransactionAspectConfig {
+
+  @Bean
+  TransactionAspect transactionAspect(MessageSerializer serializer, MessageSender sender) {
+    return new TransactionAspect(serializer, 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
new file mode 100644
index 0000000..fd7414e
--- /dev/null
+++ b/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/PreTransactionInterceptorTest.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.servicecomb.saga.omega.transaction;
+
+import static com.seanyinx.github.unit.scaffolding.Randomness.uniquify;
+import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
+import static org.junit.Assert.assertThat;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+public class PreTransactionInterceptorTest {
+  private final List<byte[]> messages = new ArrayList<>();
+
+  private final MessageSender sender = messages::add;
+  private final MessageSerializer serializer = messages -> {
+    if (messages[0] instanceof String) {
+      return ((String) messages[0]).getBytes();
+    }
+    throw new IllegalArgumentException("Expected instance of String, but was " + messages.getClass());
+  };
+
+  private final String message = uniquify("message");
+  private final PreTransactionInterceptor interceptor = new PreTransactionInterceptor(sender, serializer);
+
+  @Test
+  public void sendsSerializedMessage() throws Exception {
+    interceptor.intercept(message);
+
+    assertThat(messages, contains(message.getBytes()));
+  }
+}
diff --git a/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/TransactionInterceptionTest.java b/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/TransactionInterceptionTest.java
new file mode 100644
index 0000000..495ed27
--- /dev/null
+++ b/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/TransactionInterceptionTest.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transaction;
+
+import static com.seanyinx.github.unit.scaffolding.Randomness.uniquify;
+import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
+import static org.junit.Assert.assertThat;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import io.servicecomb.saga.omega.transaction.TransactionInterceptionTest.MessageConfig;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = {TransactionTestMain.class, MessageConfig.class})
+public class TransactionInterceptionTest {
+  private final String username = uniquify("username");
+  private final String email = uniquify("email");
+
+  @Autowired
+  private List<byte[]> messages;
+
+  @Autowired
+  private TransactionalUserService userService;
+
+  @Test
+  public void sendsUserToRemote_BeforeTransaction() throws Exception {
+    userService.add(new User(username, email));
+
+    assertThat(messages, contains((username + ":" + email).getBytes()));
+  }
+
+  @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 messages -> {
+        if (messages[0] instanceof User) {
+          User user = ((User) messages[0]);
+          return (user.username() + ":" + user.email()).getBytes();
+        }
+        throw new IllegalArgumentException("Expected instance of User, but was " + messages.getClass());
+      };
+    }
+  }
+
+}
diff --git a/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/TransactionTestMain.java b/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/TransactionTestMain.java
new file mode 100644
index 0000000..1df292c
--- /dev/null
+++ b/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/TransactionTestMain.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transaction;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class TransactionTestMain {
+  public static void main(String[] args) {
+    SpringApplication.run(TransactionTestMain.class, args);
+  }
+}
diff --git a/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/TransactionalUserService.java b/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/TransactionalUserService.java
new file mode 100644
index 0000000..d4346a0
--- /dev/null
+++ b/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/TransactionalUserService.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transaction;
+
+import javax.transaction.Transactional;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+class TransactionalUserService {
+  private final UserRepository userRepository;
+
+  @Autowired
+  TransactionalUserService(UserRepository userRepository) {
+    this.userRepository = userRepository;
+  }
+
+  @Transactional
+  void add(User user) {
+    userRepository.save(user);
+  }
+}
diff --git a/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/User.java b/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/User.java
new file mode 100644
index 0000000..f8034a7
--- /dev/null
+++ b/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/User.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.servicecomb.saga.omega.transaction;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+@Entity
+public class User {
+  @Id
+  @GeneratedValue
+  private long id;
+
+  private String username;
+  private String email;
+
+  public User(String username, String email) {
+    this.username = username;
+    this.email = email;
+  }
+
+  public long id() {
+    return id;
+  }
+
+  public String username() {
+    return username;
+  }
+
+  public String email() {
+    return email;
+  }
+}
diff --git a/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/UserRepository.java b/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/UserRepository.java
new file mode 100644
index 0000000..60cf93f
--- /dev/null
+++ b/omega/omega-transaction/src/test/java/io/servicecomb/saga/omega/transaction/UserRepository.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transaction;
+
+import org.springframework.data.repository.CrudRepository;
+
+public interface UserRepository extends CrudRepository<User, Long> {
+}

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