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 2018/01/11 02:49:11 UTC

[incubator-servicecomb-saga] 01/09: SCB-212 delegated compensation context a dedicated class

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

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

commit b85b4e95098550fe7cefe39d8aaad11d03d56d85
Author: seanyinx <se...@huawei.com>
AuthorDate: Wed Jan 10 10:19:00 2018 +0800

    SCB-212 delegated compensation context a dedicated class
    
    Signed-off-by: seanyinx <se...@huawei.com>
---
 .../saga/omega/context/CompensationContext.java    | 61 ++++++++++++++++++++++
 .../saga/omega/context/OmegaContext.java           | 40 --------------
 .../saga/omega/spring/OmegaSpringConfig.java       |  6 +++
 .../spring/CompensableAnnotationProcessor.java     |  9 +++-
 .../spring/CompensableMethodCheckingCallback.java  | 10 ++--
 .../spring/TransactionAspectConfig.java            |  7 +--
 .../transaction/CompensationMessageHandler.java    | 10 ++--
 .../saga/omega/transaction/TransactionAspect.java  |  2 +-
 .../CompensationMessageHandlerTest.java            |  8 +--
 .../TransactionClientHttpRequestInterceptor.java   | 18 +++++--
 10 files changed, 108 insertions(+), 63 deletions(-)

diff --git a/omega/omega-context/src/main/java/org/apache/servicecomb/saga/omega/context/CompensationContext.java b/omega/omega-context/src/main/java/org/apache/servicecomb/saga/omega/context/CompensationContext.java
new file mode 100644
index 0000000..118b033
--- /dev/null
+++ b/omega/omega-context/src/main/java/org/apache/servicecomb/saga/omega/context/CompensationContext.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.saga.omega.context;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CompensationContext {
+  private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+  private final Map<String, CompensationContextInternal> contexts = new HashMap<>();
+
+  public void addCompensationContext(Method compensationMethod, Object target) {
+    compensationMethod.setAccessible(true);
+    contexts.put(compensationMethod.toString(), new CompensationContextInternal(target, compensationMethod));
+  }
+
+  public void compensate(String globalTxId, String localTxId, String compensationMethod, Object... payloads) {
+    CompensationContextInternal contextInternal = contexts.get(compensationMethod);
+
+    try {
+      contextInternal.compensationMethod.invoke(contextInternal.target, payloads);
+      LOG.info("Compensated transaction with global tx id [{}], local tx id [{}]", globalTxId, localTxId);
+    } catch (IllegalAccessException | InvocationTargetException e) {
+      LOG.error(
+          "Pre-checking for compensate method " + contextInternal.compensationMethod.toString()
+              + " was somehow skipped, did you forget to configure compensable method checking on service startup?",
+          e);
+    }
+  }
+
+  private static final class CompensationContextInternal {
+    private final Object target;
+    private final Method compensationMethod;
+
+    private CompensationContextInternal(Object target, Method compensationMethod) {
+      this.target = target;
+      this.compensationMethod = compensationMethod;
+    }
+  }
+}
\ No newline at end of file
diff --git a/omega/omega-context/src/main/java/org/apache/servicecomb/saga/omega/context/OmegaContext.java b/omega/omega-context/src/main/java/org/apache/servicecomb/saga/omega/context/OmegaContext.java
index 94de6ef..43bf0b4 100644
--- a/omega/omega-context/src/main/java/org/apache/servicecomb/saga/omega/context/OmegaContext.java
+++ b/omega/omega-context/src/main/java/org/apache/servicecomb/saga/omega/context/OmegaContext.java
@@ -17,17 +17,7 @@
 
 package org.apache.servicecomb.saga.omega.context;
 
-import java.lang.invoke.MethodHandles;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 public class OmegaContext {
-  private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
   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";
 
@@ -35,7 +25,6 @@ public class OmegaContext {
   private final ThreadLocal<String> localTxId = new InheritableThreadLocal<>();
   private final ThreadLocal<String> parentTxId = new InheritableThreadLocal<>();
   private final IdGenerator<String> idGenerator;
-  private final Map<String, CompensationContext> compensationContexts = new HashMap<>();
 
   public OmegaContext(IdGenerator<String> idGenerator) {
     this.idGenerator = idGenerator;
@@ -83,25 +72,6 @@ public class OmegaContext {
     parentTxId.remove();
   }
 
-  public void addCompensationContext(Method compensationMethod, Object target) {
-    compensationMethod.setAccessible(true);
-    compensationContexts.put(compensationMethod.toString(), new CompensationContext(target, compensationMethod));
-  }
-
-  public void compensate(String globalTxId, String localTxId, String compensationMethod, Object... payloads) {
-    CompensationContext compensationContext = compensationContexts.get(compensationMethod);
-
-    try {
-      compensationContext.compensationMethod.invoke(compensationContext.target, payloads);
-      LOG.info("Compensated transaction with global tx id [{}], local tx id [{}]", globalTxId, localTxId);
-    } catch (IllegalAccessException | InvocationTargetException e) {
-      LOG.error(
-          "Pre-checking for compensate method " + compensationContext.compensationMethod.toString()
-              + " was somehow skipped, did you forget to configure compensable method checking on service startup?",
-          e);
-    }
-  }
-
   @Override
   public String toString() {
     return "OmegaContext{" +
@@ -110,14 +80,4 @@ public class OmegaContext {
         ", parentTxId=" + parentTxId.get() +
         '}';
   }
-
-  private static final class CompensationContext {
-    private final Object target;
-    private final Method compensationMethod;
-
-    private CompensationContext(Object target, Method compensationMethod) {
-      this.target = target;
-      this.compensationMethod = compensationMethod;
-    }
-  }
 }
diff --git a/omega/omega-spring-starter/src/main/java/org/apache/servicecomb/saga/omega/spring/OmegaSpringConfig.java b/omega/omega-spring-starter/src/main/java/org/apache/servicecomb/saga/omega/spring/OmegaSpringConfig.java
index e5806ad..fa4027b 100644
--- a/omega/omega-spring-starter/src/main/java/org/apache/servicecomb/saga/omega/spring/OmegaSpringConfig.java
+++ b/omega/omega-spring-starter/src/main/java/org/apache/servicecomb/saga/omega/spring/OmegaSpringConfig.java
@@ -18,6 +18,7 @@
 package org.apache.servicecomb.saga.omega.spring;
 
 import org.apache.servicecomb.saga.omega.connector.grpc.LoadBalancedClusterMessageSender;
+import org.apache.servicecomb.saga.omega.context.CompensationContext;
 import org.apache.servicecomb.saga.omega.context.IdGenerator;
 import org.apache.servicecomb.saga.omega.context.OmegaContext;
 import org.apache.servicecomb.saga.omega.context.ServiceConfig;
@@ -45,6 +46,11 @@ class OmegaSpringConfig {
   }
 
   @Bean
+  CompensationContext compensationContext() {
+    return new CompensationContext();
+  }
+
+  @Bean
   ServiceConfig serviceConfig(@Value("${spring.application.name}") String serviceName) {
     return new ServiceConfig(serviceName);
   }
diff --git a/omega/omega-spring-tx/src/main/java/org/apache/servicecomb/saga/omega/transaction/spring/CompensableAnnotationProcessor.java b/omega/omega-spring-tx/src/main/java/org/apache/servicecomb/saga/omega/transaction/spring/CompensableAnnotationProcessor.java
index 87f9049..338751c 100644
--- a/omega/omega-spring-tx/src/main/java/org/apache/servicecomb/saga/omega/transaction/spring/CompensableAnnotationProcessor.java
+++ b/omega/omega-spring-tx/src/main/java/org/apache/servicecomb/saga/omega/transaction/spring/CompensableAnnotationProcessor.java
@@ -17,6 +17,7 @@
 
 package org.apache.servicecomb.saga.omega.transaction.spring;
 
+import org.apache.servicecomb.saga.omega.context.CompensationContext;
 import org.apache.servicecomb.saga.omega.context.OmegaContext;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.config.BeanPostProcessor;
@@ -25,9 +26,11 @@ import org.springframework.util.ReflectionUtils;
 class CompensableAnnotationProcessor implements BeanPostProcessor {
 
   private final OmegaContext omegaContext;
+  private final CompensationContext compensationContext;
 
-  CompensableAnnotationProcessor(OmegaContext omegaContext) {
+  CompensableAnnotationProcessor(OmegaContext omegaContext, CompensationContext compensationContext) {
     this.omegaContext = omegaContext;
+    this.compensationContext = compensationContext;
   }
 
   @Override
@@ -43,7 +46,9 @@ class CompensableAnnotationProcessor implements BeanPostProcessor {
   }
 
   private void checkMethod(Object bean) {
-    ReflectionUtils.doWithMethods(bean.getClass(), new CompensableMethodCheckingCallback(bean, omegaContext));
+    ReflectionUtils.doWithMethods(
+        bean.getClass(),
+        new CompensableMethodCheckingCallback(bean, compensationContext));
   }
 
   private void checkFields(Object bean) {
diff --git a/omega/omega-spring-tx/src/main/java/org/apache/servicecomb/saga/omega/transaction/spring/CompensableMethodCheckingCallback.java b/omega/omega-spring-tx/src/main/java/org/apache/servicecomb/saga/omega/transaction/spring/CompensableMethodCheckingCallback.java
index ac6615c..6c0c333 100644
--- a/omega/omega-spring-tx/src/main/java/org/apache/servicecomb/saga/omega/transaction/spring/CompensableMethodCheckingCallback.java
+++ b/omega/omega-spring-tx/src/main/java/org/apache/servicecomb/saga/omega/transaction/spring/CompensableMethodCheckingCallback.java
@@ -20,7 +20,7 @@ package org.apache.servicecomb.saga.omega.transaction.spring;
 import java.lang.invoke.MethodHandles;
 import java.lang.reflect.Method;
 
-import org.apache.servicecomb.saga.omega.context.OmegaContext;
+import org.apache.servicecomb.saga.omega.context.CompensationContext;
 import org.apache.servicecomb.saga.omega.transaction.OmegaException;
 import org.apache.servicecomb.saga.omega.transaction.annotations.Compensable;
 import org.slf4j.Logger;
@@ -31,11 +31,11 @@ class CompensableMethodCheckingCallback implements MethodCallback {
   private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   private final Object bean;
-  private final OmegaContext omegaContext;
+  private final CompensationContext compensationContext;
 
-  CompensableMethodCheckingCallback(Object bean, OmegaContext omegaContext) {
+  CompensableMethodCheckingCallback(Object bean, CompensationContext compensationContext) {
     this.bean = bean;
-    this.omegaContext = omegaContext;
+    this.compensationContext = compensationContext;
   }
 
   @Override
@@ -48,7 +48,7 @@ class CompensableMethodCheckingCallback implements MethodCallback {
 
     try {
       Method signature = bean.getClass().getDeclaredMethod(compensationMethod, method.getParameterTypes());
-      omegaContext.addCompensationContext(signature, bean);
+      compensationContext.addCompensationContext(signature, bean);
       LOG.debug("Found compensation method [{}] in {}", compensationMethod, bean.getClass().getCanonicalName());
     } catch (NoSuchMethodException e) {
       throw new OmegaException(
diff --git a/omega/omega-spring-tx/src/main/java/org/apache/servicecomb/saga/omega/transaction/spring/TransactionAspectConfig.java b/omega/omega-spring-tx/src/main/java/org/apache/servicecomb/saga/omega/transaction/spring/TransactionAspectConfig.java
index 1d46378..dc88bbd 100644
--- a/omega/omega-spring-tx/src/main/java/org/apache/servicecomb/saga/omega/transaction/spring/TransactionAspectConfig.java
+++ b/omega/omega-spring-tx/src/main/java/org/apache/servicecomb/saga/omega/transaction/spring/TransactionAspectConfig.java
@@ -17,6 +17,7 @@
 
 package org.apache.servicecomb.saga.omega.transaction.spring;
 
+import org.apache.servicecomb.saga.omega.context.CompensationContext;
 import org.apache.servicecomb.saga.omega.context.OmegaContext;
 import org.apache.servicecomb.saga.omega.transaction.CompensationMessageHandler;
 import org.apache.servicecomb.saga.omega.transaction.MessageHandler;
@@ -31,7 +32,7 @@ import org.springframework.context.annotation.EnableAspectJAutoProxy;
 public class TransactionAspectConfig {
 
   @Bean
-  MessageHandler messageHandler(MessageSender sender, OmegaContext context) {
+  MessageHandler messageHandler(MessageSender sender, CompensationContext context) {
     return new CompensationMessageHandler(sender, context);
   }
 
@@ -41,7 +42,7 @@ public class TransactionAspectConfig {
   }
 
   @Bean
-  CompensableAnnotationProcessor compensableAnnotationProcessor(OmegaContext omegaContext) {
-    return new CompensableAnnotationProcessor(omegaContext);
+  CompensableAnnotationProcessor compensableAnnotationProcessor(OmegaContext omegaContext, CompensationContext compensationContext) {
+    return new CompensableAnnotationProcessor(omegaContext, compensationContext);
   }
 }
diff --git a/omega/omega-transaction/src/main/java/org/apache/servicecomb/saga/omega/transaction/CompensationMessageHandler.java b/omega/omega-transaction/src/main/java/org/apache/servicecomb/saga/omega/transaction/CompensationMessageHandler.java
index 2e0836e..46c1e9b 100644
--- a/omega/omega-transaction/src/main/java/org/apache/servicecomb/saga/omega/transaction/CompensationMessageHandler.java
+++ b/omega/omega-transaction/src/main/java/org/apache/servicecomb/saga/omega/transaction/CompensationMessageHandler.java
@@ -17,20 +17,20 @@
 
 package org.apache.servicecomb.saga.omega.transaction;
 
-import org.apache.servicecomb.saga.omega.context.OmegaContext;
+import org.apache.servicecomb.saga.omega.context.CompensationContext;
 
 public class CompensationMessageHandler implements MessageHandler {
   private final MessageSender sender;
-  private final OmegaContext omegaContext;
+  private final CompensationContext context;
 
-  public CompensationMessageHandler(MessageSender sender, OmegaContext omegaContext) {
+  public CompensationMessageHandler(MessageSender sender, CompensationContext context) {
     this.sender = sender;
-    this.omegaContext = omegaContext;
+    this.context = context;
   }
 
   @Override
   public void onReceive(String globalTxId, String localTxId, String parentTxId, String compensationMethod, Object... payloads) {
-    omegaContext.compensate(globalTxId, localTxId, compensationMethod, payloads);
+    context.compensate(globalTxId, localTxId, compensationMethod, payloads);
     sender.send(new TxCompensatedEvent(globalTxId, localTxId, parentTxId, compensationMethod));
   }
 }
diff --git a/omega/omega-transaction/src/main/java/org/apache/servicecomb/saga/omega/transaction/TransactionAspect.java b/omega/omega-transaction/src/main/java/org/apache/servicecomb/saga/omega/transaction/TransactionAspect.java
index bf13e3a..d141d0c 100644
--- a/omega/omega-transaction/src/main/java/org/apache/servicecomb/saga/omega/transaction/TransactionAspect.java
+++ b/omega/omega-transaction/src/main/java/org/apache/servicecomb/saga/omega/transaction/TransactionAspect.java
@@ -44,7 +44,7 @@ public class TransactionAspect {
     this.preTransactionInterceptor = new PreTransactionInterceptor(sender);
     this.postTransactionInterceptor = new PostTransactionInterceptor(sender);
     this.failedTransactionInterceptor = new FailedTransactionInterceptor(sender);
-    this.sagaStartAnnotationProcessor = new SagaStartAnnotationProcessor(this.context, sender);
+    this.sagaStartAnnotationProcessor = new SagaStartAnnotationProcessor(context, sender);
   }
 
   @Around("execution(@org.apache.servicecomb.saga.omega.transaction.annotations.Compensable * *(..)) && @annotation(compensable)")
diff --git a/omega/omega-transaction/src/test/java/org/apache/servicecomb/saga/omega/transaction/CompensationMessageHandlerTest.java b/omega/omega-transaction/src/test/java/org/apache/servicecomb/saga/omega/transaction/CompensationMessageHandlerTest.java
index 2ecd82f..2585f3f 100644
--- a/omega/omega-transaction/src/test/java/org/apache/servicecomb/saga/omega/transaction/CompensationMessageHandlerTest.java
+++ b/omega/omega-transaction/src/test/java/org/apache/servicecomb/saga/omega/transaction/CompensationMessageHandlerTest.java
@@ -26,7 +26,7 @@ import static org.mockito.Mockito.verify;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.servicecomb.saga.omega.context.OmegaContext;
+import org.apache.servicecomb.saga.omega.context.CompensationContext;
 import org.junit.Test;
 
 public class CompensationMessageHandlerTest {
@@ -40,8 +40,8 @@ public class CompensationMessageHandlerTest {
   private final String compensationMethod = getClass().getCanonicalName();
   private final String payload = uniquify("blah");
 
-  private final OmegaContext omegaContext = mock(OmegaContext.class);
-  private final CompensationMessageHandler handler = new CompensationMessageHandler(sender, omegaContext);
+  private final CompensationContext context = mock(CompensationContext.class);
+  private final CompensationMessageHandler handler = new CompensationMessageHandler(sender, context);
 
   @Test
   public void sendsEventOnCompensationCompleted() throws Exception {
@@ -57,6 +57,6 @@ public class CompensationMessageHandlerTest {
     assertThat(event.compensationMethod(), is(getClass().getCanonicalName()));
     assertThat(event.payloads().length, is(0));
 
-    verify(omegaContext).compensate(globalTxId, localTxId, compensationMethod, payload);
+    verify(context).compensate(globalTxId, localTxId, compensationMethod, payload);
   }
 }
diff --git a/omega/omega-transport/omega-transport-resttemplate/src/main/java/org/apache/servicecomb/saga/omega/transport/resttemplate/TransactionClientHttpRequestInterceptor.java b/omega/omega-transport/omega-transport-resttemplate/src/main/java/org/apache/servicecomb/saga/omega/transport/resttemplate/TransactionClientHttpRequestInterceptor.java
index 5e69598..88ea564 100644
--- a/omega/omega-transport/omega-transport-resttemplate/src/main/java/org/apache/servicecomb/saga/omega/transport/resttemplate/TransactionClientHttpRequestInterceptor.java
+++ b/omega/omega-transport/omega-transport-resttemplate/src/main/java/org/apache/servicecomb/saga/omega/transport/resttemplate/TransactionClientHttpRequestInterceptor.java
@@ -18,16 +18,22 @@
 
 package org.apache.servicecomb.saga.omega.transport.resttemplate;
 
+import static org.apache.servicecomb.saga.omega.context.OmegaContext.GLOBAL_TX_ID_KEY;
+import static org.apache.servicecomb.saga.omega.context.OmegaContext.LOCAL_TX_ID_KEY;
+
 import java.io.IOException;
+import java.lang.invoke.MethodHandles;
 
 import org.apache.servicecomb.saga.omega.context.OmegaContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.http.HttpRequest;
 import org.springframework.http.client.ClientHttpRequestExecution;
 import org.springframework.http.client.ClientHttpRequestInterceptor;
 import org.springframework.http.client.ClientHttpResponse;
 
 class TransactionClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
-
+  private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
   private final OmegaContext omegaContext;
 
   TransactionClientHttpRequestInterceptor(OmegaContext omegaContext) {
@@ -39,8 +45,14 @@ class TransactionClientHttpRequestInterceptor implements ClientHttpRequestInterc
       ClientHttpRequestExecution execution) throws IOException {
 
     if (omegaContext.globalTxId() != null) {
-      request.getHeaders().add(OmegaContext.GLOBAL_TX_ID_KEY, omegaContext.globalTxId());
-      request.getHeaders().add(OmegaContext.LOCAL_TX_ID_KEY, omegaContext.localTxId());
+      request.getHeaders().add(GLOBAL_TX_ID_KEY, omegaContext.globalTxId());
+      request.getHeaders().add(LOCAL_TX_ID_KEY, omegaContext.localTxId());
+
+      LOG.debug("Added {} {} and {} {} to request header",
+          GLOBAL_TX_ID_KEY,
+          omegaContext.globalTxId(),
+          LOCAL_TX_ID_KEY,
+          omegaContext.localTxId());
     }
     return execution.execute(request, body);
   }

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