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 2019/08/02 00:09:37 UTC

[servicecomb-pack] branch master updated (135e6e9 -> b8abd1a)

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

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


    from 135e6e9  SCB-1399 Remove parameter -P${SPRING_BOOT_PROFILE}
     new a5be2be  SCB-1386 Introduce sendingSagaEnd attribute to let user choise  when to send SagaEnd event
     new 0dbc07d  SCB-1386 Fixed the test error in SagaStartAspectTest
     new a47e27c  SCB-1386 using autoClose attribute in SagaStart
     new b41760c  SCB-1386 Introduced SagaEnd annotation, rervert the changes of Compensiable
     new 4cd1f5e  SCB-1386 Polish the code and fix the integration test error
     new b8abd1a  SCB-1386 Added some comments on the SagaEnd annotation.

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


Summary of changes:
 .../pack/omega/context/annotations/SagaEnd.java    | 18 ++---
 .../pack/omega/context/annotations/SagaStart.java  |  7 ++
 omega/omega-transaction/pom.xml                    |  4 +
 .../omega/transaction/AbstractRecoveryPolicy.java  | 10 ++-
 .../omega/transaction/CompensableInterceptor.java  |  1 +
 .../pack/omega/transaction/SagaEndAspect.java      | 74 ++++++++++++++++++
 .../transaction/SagaStartAnnotationProcessor.java  |  1 +
 .../pack/omega/transaction/SagaStartAspect.java    |  2 +
 .../pack/omega/transaction/TransactionAspect.java  |  2 +
 .../omega/transaction/annotations/Compensable.java |  1 +
 .../SagaStartAnnotationProcessorWrapper.java       |  8 +-
 ...StartAspectTest.java => SagaEndAspectTest.java} | 89 ++++++----------------
 .../omega/transaction/SagaStartAspectTest.java     | 21 +++++
 .../omega/transaction/TransactionAspectTest.java   |  4 +-
 14 files changed, 160 insertions(+), 82 deletions(-)
 copy acceptance-tests/acceptance-pack-cluster-spring-demo/src/test/java/org/apache/servicecomb/pack/RunCucumberIT.java => omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/annotations/SagaEnd.java (70%)
 create mode 100644 omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/SagaEndAspect.java
 copy omega/omega-transaction/src/test/java/org/apache/servicecomb/pack/omega/transaction/{SagaStartAspectTest.java => SagaEndAspectTest.java} (56%)


[servicecomb-pack] 01/06: SCB-1386 Introduce sendingSagaEnd attribute to let user choise when to send SagaEnd event

Posted by ni...@apache.org.
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/servicecomb-pack.git

commit a5be2bea3965488d38e60e3891523be3c545ef35
Author: Willem Jiang <wi...@gmail.com>
AuthorDate: Sun Jul 28 16:48:28 2019 +0800

    SCB-1386 Introduce sendingSagaEnd attribute to let user choise  when to send SagaEnd event
---
 .../pack/omega/context/annotations/SagaStart.java  |  7 +++++
 .../omega/transaction/AbstractRecoveryPolicy.java  | 13 +++++++--
 .../omega/transaction/CompensableInterceptor.java  |  4 +++
 .../transaction/SagaStartAnnotationProcessor.java  |  1 +
 .../omega/transaction/annotations/Compensable.java |  7 +++++
 .../SagaStartAnnotationProcessorWrapper.java       |  8 ++++--
 .../omega/transaction/TransactionAspectTest.java   | 33 +++++++++++++++++++++-
 7 files changed, 68 insertions(+), 5 deletions(-)

diff --git a/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/annotations/SagaStart.java b/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/annotations/SagaStart.java
index 2a66a84..7517bd4 100644
--- a/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/annotations/SagaStart.java
+++ b/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/annotations/SagaStart.java
@@ -37,4 +37,11 @@ public @interface SagaStart {
    * @return
    */
   int timeout() default 0;
+
+  /**
+   * Sending out SagaEnd event to Alpha once the SagaStart annotated method is finished without any error.
+   * Default value is true, which means Omega sends out the SagaEnd event to Alpha once the annotated method is finished.
+   * Value is false, which means Omega never sends out the SagaEnd event to Alpha once the annotated method is finished.
+   */
+  boolean sendingSagaEnd() default true;
 }
diff --git a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/AbstractRecoveryPolicy.java b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/AbstractRecoveryPolicy.java
index 8526581..a97f118 100644
--- a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/AbstractRecoveryPolicy.java
+++ b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/AbstractRecoveryPolicy.java
@@ -32,11 +32,20 @@ public abstract class AbstractRecoveryPolicy implements RecoveryPolicy {
   public Object apply(ProceedingJoinPoint joinPoint, Compensable compensable,
       CompensableInterceptor interceptor, OmegaContext context, String parentTxId, int retries)
       throws Throwable {
+    Object result;
     if(compensable.timeout()>0){
       RecoveryPolicyTimeoutWrapper wrapper = new RecoveryPolicyTimeoutWrapper(this);
-      return wrapper.applyTo(joinPoint, compensable, interceptor, context, parentTxId, retries);
+      result = wrapper.applyTo(joinPoint, compensable, interceptor, context, parentTxId, retries);
     }else{
-      return this.applyTo(joinPoint, compensable, interceptor, context, parentTxId, retries);
+      result = this.applyTo(joinPoint, compensable, interceptor, context, parentTxId, retries);
     }
+    if (compensable.sendingSagaEnd()) {
+      // Just send out the SagaEnd event
+      // TODO we may also invoke the callback here to release some resources
+      interceptor.sendSagaEndEvent();
+    }
+    return result;
   }
+
+
 }
diff --git a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/CompensableInterceptor.java b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/CompensableInterceptor.java
index 08ad7f7..1f4a119 100644
--- a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/CompensableInterceptor.java
+++ b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/CompensableInterceptor.java
@@ -45,4 +45,8 @@ public class CompensableInterceptor implements EventAwareInterceptor {
     sender.send(
         new TxAbortedEvent(context.globalTxId(), context.localTxId(), parentTxId, compensationMethod, throwable));
   }
+  
+  public void sendSagaEndEvent() {
+    sender.send(new SagaEndedEvent(context.globalTxId(), context.localTxId()));
+  }
 }
diff --git a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/SagaStartAnnotationProcessor.java b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/SagaStartAnnotationProcessor.java
index 767171b..de9aa3f 100644
--- a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/SagaStartAnnotationProcessor.java
+++ b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/SagaStartAnnotationProcessor.java
@@ -42,6 +42,7 @@ public class SagaStartAnnotationProcessor {
   public void postIntercept(String parentTxId) {
     AlphaResponse response = sender
         .send(new SagaEndedEvent(omegaContext.globalTxId(), omegaContext.localTxId()));
+    //TODO we may know if the transaction is aborted from fsm alpha backend
     if (response.aborted()) {
       throw new OmegaException("transaction " + parentTxId + " is aborted");
     }
diff --git a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/annotations/Compensable.java b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/annotations/Compensable.java
index 0e24029..0272d29 100644
--- a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/annotations/Compensable.java
+++ b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/annotations/Compensable.java
@@ -72,4 +72,11 @@ public @interface Compensable {
    * @return the timeout value
    */
   int timeout() default 0;
+
+  /**
+   * Sending out SagaEnd event to Alpha once the SagaStart annotated method is finished without any error.
+   * Default value is false, which means Omega never send out the SagaEnd event to Alpha once the annotated method is finished.
+   * value is true, means this method is last compensable method need to be called, Omega will send SagaEnd event to Alpha once the method is finished.
+   */
+  boolean sendingSagaEnd() default false;
 }
diff --git a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/wrapper/SagaStartAnnotationProcessorWrapper.java b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/wrapper/SagaStartAnnotationProcessorWrapper.java
index 2837c7f..f71e507 100644
--- a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/wrapper/SagaStartAnnotationProcessorWrapper.java
+++ b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/wrapper/SagaStartAnnotationProcessorWrapper.java
@@ -45,8 +45,12 @@ public class SagaStartAnnotationProcessorWrapper {
     LOG.debug("Initialized context {} before execution of method {}", context, method.toString());
     try {
       Object result = joinPoint.proceed();
-      sagaStartAnnotationProcessor.postIntercept(context.globalTxId());
-      LOG.debug("Transaction with context {} has finished.", context);
+      if (sagaStart.sendingSagaEnd()) {
+        sagaStartAnnotationProcessor.postIntercept(context.globalTxId());
+        LOG.debug("Transaction with context {} has finished.", context);
+      } else {
+        LOG.debug("Transaction with context {} is not finished in the SagaStarted annotated method.", context);
+      }
       return result;
     } catch (Throwable throwable) {
       // We don't need to handle the OmegaException here
diff --git a/omega/omega-transaction/src/test/java/org/apache/servicecomb/pack/omega/transaction/TransactionAspectTest.java b/omega/omega-transaction/src/test/java/org/apache/servicecomb/pack/omega/transaction/TransactionAspectTest.java
index 4c5ad4c..3de4013 100644
--- a/omega/omega-transaction/src/test/java/org/apache/servicecomb/pack/omega/transaction/TransactionAspectTest.java
+++ b/omega/omega-transaction/src/test/java/org/apache/servicecomb/pack/omega/transaction/TransactionAspectTest.java
@@ -20,6 +20,7 @@ package org.apache.servicecomb.pack.omega.transaction;
 import static com.seanyinx.github.unit.scaffolding.AssertUtils.expectFailing;
 import static org.hamcrest.core.Is.is;
 import static org.hamcrest.core.IsInstanceOf.instanceOf;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -110,10 +111,40 @@ public class TransactionAspectTest {
   }
 
   @Test
+  public void sendingSageEndEvent() throws Throwable {
+    when(compensable.sendingSagaEnd()).thenReturn(true);
+    aspect.advise(joinPoint, compensable);
+    assertThat(messages.size(), is(3));
+
+    TxEvent startedEvent = messages.get(0);
+
+    assertThat(startedEvent.globalTxId(), is(globalTxId));
+    assertThat(startedEvent.localTxId(), is(newLocalTxId));
+    assertThat(startedEvent.parentTxId(), is(localTxId));
+    assertThat(startedEvent.type(), is(EventType.TxStartedEvent));
+    assertThat(startedEvent.retries(), is(0));
+    assertThat(startedEvent.retryMethod().isEmpty(), is(true));
+
+    TxEvent endedEvent = messages.get(1);
+
+    assertThat(endedEvent.globalTxId(), is(globalTxId));
+    assertThat(endedEvent.localTxId(), is(newLocalTxId));
+    assertThat(endedEvent.parentTxId(), is(localTxId));
+    assertThat(endedEvent.type(), is(EventType.TxEndedEvent));
+
+    TxEvent sagaEndEvent = messages.get(2);
+    assertThat(sagaEndEvent.globalTxId(), is(globalTxId));
+    assertNull(sagaEndEvent.parentTxId());
+    assertThat(sagaEndEvent.localTxId(), is(newLocalTxId));
+    assertThat(sagaEndEvent.type(), is(EventType.SagaEndedEvent));
+  }
+
+  @Test
   public void setNewLocalTxIdCompensableWithTransactionContext() throws Throwable {
     // setup the argument class
     when(joinPoint.getArgs()).thenReturn(new Object[]{transactionContextProperties});
     aspect.advise(joinPoint, compensable);
+    assertThat(messages.size(), is(2));
     TxEvent startedEvent = messages.get(0);
 
     assertThat(startedEvent.globalTxId(), is(transactionGlobalTxId));
@@ -137,7 +168,7 @@ public class TransactionAspectTest {
   @Test
   public void newLocalTxIdInCompensable() throws Throwable {
     aspect.advise(joinPoint, compensable);
-
+    assertThat(messages.size(), is(2));
     TxEvent startedEvent = messages.get(0);
 
     assertThat(startedEvent.globalTxId(), is(globalTxId));


[servicecomb-pack] 02/06: SCB-1386 Fixed the test error in SagaStartAspectTest

Posted by ni...@apache.org.
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/servicecomb-pack.git

commit 0dbc07d0656f77a622549445d65b61b8d01869ff
Author: Willem Jiang <wi...@gmail.com>
AuthorDate: Sun Jul 28 16:55:16 2019 +0800

    SCB-1386 Fixed the test error in SagaStartAspectTest
---
 .../pack/omega/transaction/SagaStartAspectTest.java | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/omega/omega-transaction/src/test/java/org/apache/servicecomb/pack/omega/transaction/SagaStartAspectTest.java b/omega/omega-transaction/src/test/java/org/apache/servicecomb/pack/omega/transaction/SagaStartAspectTest.java
index 656eac1..c03a594 100644
--- a/omega/omega-transaction/src/test/java/org/apache/servicecomb/pack/omega/transaction/SagaStartAspectTest.java
+++ b/omega/omega-transaction/src/test/java/org/apache/servicecomb/pack/omega/transaction/SagaStartAspectTest.java
@@ -80,6 +80,8 @@ public class SagaStartAspectTest {
     when(idGenerator.nextId()).thenReturn(globalTxId);
     when(joinPoint.getSignature()).thenReturn(methodSignature);
     when(methodSignature.getMethod()).thenReturn(this.getClass().getDeclaredMethod("doNothing"));
+    // setup the default value of SagaStart
+    when(sagaStart.sendingSagaEnd()).thenReturn(true);
   }
 
   @Test
@@ -107,6 +109,25 @@ public class SagaStartAspectTest {
   }
 
   @Test
+  public void dontSendingSagaEndMessage() throws Throwable {
+    when(sagaStart.sendingSagaEnd()).thenReturn(false);
+    omegaContext = new OmegaContext(idGenerator);
+    aspect = new SagaStartAspect(sender, omegaContext);
+
+    aspect.advise(joinPoint, sagaStart);
+    assertThat(messages.size(), is(1));
+    TxEvent startedEvent = messages.get(0);
+
+    assertThat(startedEvent.globalTxId(), is(globalTxId));
+    assertThat(startedEvent.localTxId(), is(globalTxId));
+    assertThat(startedEvent.parentTxId(), is(nullValue()));
+    assertThat(startedEvent.type(), is(EventType.SagaStartedEvent));
+
+    assertThat(omegaContext.globalTxId(), is(nullValue()));
+    assertThat(omegaContext.localTxId(), is(nullValue()));
+  }
+
+  @Test
   public void clearContextOnSagaStartError() throws Throwable {
     omegaContext = new OmegaContext(idGenerator);
     aspect = new SagaStartAspect(sender, omegaContext);


[servicecomb-pack] 05/06: SCB-1386 Polish the code and fix the integration test error

Posted by ni...@apache.org.
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/servicecomb-pack.git

commit 4cd1f5e39f8ad5c44e545710ec9ba4389e451781
Author: Willem Jiang <wi...@gmail.com>
AuthorDate: Thu Aug 1 15:41:49 2019 +0800

    SCB-1386 Polish the code and fix the integration test error
---
 .../org/apache/servicecomb/pack/omega/context/annotations/SagaEnd.java | 2 +-
 .../org/apache/servicecomb/pack/omega/transaction/SagaEndAspect.java   | 3 +--
 .../org/apache/servicecomb/pack/omega/transaction/SagaStartAspect.java | 2 ++
 .../apache/servicecomb/pack/omega/transaction/TransactionAspect.java   | 2 +-
 4 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/annotations/SagaEnd.java b/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/annotations/SagaEnd.java
index b7309b9..23c3666 100644
--- a/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/annotations/SagaEnd.java
+++ b/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/annotations/SagaEnd.java
@@ -17,7 +17,7 @@
 package org.apache.servicecomb.pack.omega.context.annotations;
 
 /**
- * Indicates once the annotated method is finised, it will end a saga.
+ * Indicates once the annotated method is finished, it will end a saga.
  */
 public class SagaEnd {
 
diff --git a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/SagaEndAspect.java b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/SagaEndAspect.java
index 14e1041..7c39580 100644
--- a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/SagaEndAspect.java
+++ b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/SagaEndAspect.java
@@ -21,7 +21,6 @@ import java.lang.reflect.Method;
 
 import org.apache.servicecomb.pack.omega.context.OmegaContext;
 import org.apache.servicecomb.pack.omega.context.annotations.SagaEnd;
-import org.apache.servicecomb.pack.omega.context.annotations.SagaStart;
 import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;
@@ -31,7 +30,7 @@ import org.slf4j.LoggerFactory;
 import org.springframework.core.annotation.Order;
 
 @Aspect
-@Order(value = 100)
+@Order(value = 300)
 public class SagaEndAspect {
   private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
   private final OmegaContext context;
diff --git a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/SagaStartAspect.java b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/SagaStartAspect.java
index 51eba27..650448d 100644
--- a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/SagaStartAspect.java
+++ b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/SagaStartAspect.java
@@ -24,8 +24,10 @@ import org.apache.servicecomb.pack.omega.transaction.wrapper.SagaStartAnnotation
 import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;
+import org.springframework.core.annotation.Order;
 
 @Aspect
+@Order(value = 100)
 public class SagaStartAspect {
 
   private final SagaStartAnnotationProcessor sagaStartAnnotationProcessor;
diff --git a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/TransactionAspect.java b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/TransactionAspect.java
index b79e565..7632e7c 100644
--- a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/TransactionAspect.java
+++ b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/TransactionAspect.java
@@ -32,7 +32,7 @@ import org.slf4j.LoggerFactory;
 import org.springframework.core.annotation.Order;
 
 @Aspect
-@Order(value=10)
+@Order(value = 200)
 public class TransactionAspect extends TransactionContextHelper {
 
   private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());


[servicecomb-pack] 04/06: SCB-1386 Introduced SagaEnd annotation, rervert the changes of Compensiable

Posted by ni...@apache.org.
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/servicecomb-pack.git

commit b41760ceac6870996d68f1c88e73574e33e4e9d6
Author: Willem Jiang <wi...@gmail.com>
AuthorDate: Wed Jul 31 10:04:40 2019 +0800

    SCB-1386 Introduced SagaEnd annotation, rervert the changes of Compensiable
---
 .../pack/omega/context/annotations/SagaEnd.java    |  24 ++++
 omega/omega-transaction/pom.xml                    |   4 +
 .../omega/transaction/AbstractRecoveryPolicy.java  |   7 +-
 .../omega/transaction/CompensableInterceptor.java  |   5 +-
 .../pack/omega/transaction/SagaEndAspect.java      |  75 +++++++++++
 .../pack/omega/transaction/TransactionAspect.java  |   2 +
 .../omega/transaction/annotations/Compensable.java |   6 -
 .../pack/omega/transaction/SagaEndAspectTest.java  | 137 +++++++++++++++++++++
 .../omega/transaction/TransactionAspectTest.java   |  29 -----
 9 files changed, 244 insertions(+), 45 deletions(-)

diff --git a/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/annotations/SagaEnd.java b/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/annotations/SagaEnd.java
new file mode 100644
index 0000000..b7309b9
--- /dev/null
+++ b/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/annotations/SagaEnd.java
@@ -0,0 +1,24 @@
+/*
+ * 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.pack.omega.context.annotations;
+
+/**
+ * Indicates once the annotated method is finised, it will end a saga.
+ */
+public class SagaEnd {
+
+}
diff --git a/omega/omega-transaction/pom.xml b/omega/omega-transaction/pom.xml
index c96a7cc..ba1a0cc 100644
--- a/omega/omega-transaction/pom.xml
+++ b/omega/omega-transaction/pom.xml
@@ -50,6 +50,10 @@
       <groupId>javax.transaction</groupId>
       <artifactId>javax.transaction-api</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-core</artifactId>
+    </dependency>
 
     <dependency>
       <groupId>junit</groupId>
diff --git a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/AbstractRecoveryPolicy.java b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/AbstractRecoveryPolicy.java
index a97f118..6e86d72 100644
--- a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/AbstractRecoveryPolicy.java
+++ b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/AbstractRecoveryPolicy.java
@@ -36,14 +36,9 @@ public abstract class AbstractRecoveryPolicy implements RecoveryPolicy {
     if(compensable.timeout()>0){
       RecoveryPolicyTimeoutWrapper wrapper = new RecoveryPolicyTimeoutWrapper(this);
       result = wrapper.applyTo(joinPoint, compensable, interceptor, context, parentTxId, retries);
-    }else{
+    } else {
       result = this.applyTo(joinPoint, compensable, interceptor, context, parentTxId, retries);
     }
-    if (compensable.sendingSagaEnd()) {
-      // Just send out the SagaEnd event
-      // TODO we may also invoke the callback here to release some resources
-      interceptor.sendSagaEndEvent();
-    }
     return result;
   }
 
diff --git a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/CompensableInterceptor.java b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/CompensableInterceptor.java
index 1f4a119..108ebbc 100644
--- a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/CompensableInterceptor.java
+++ b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/CompensableInterceptor.java
@@ -45,8 +45,5 @@ public class CompensableInterceptor implements EventAwareInterceptor {
     sender.send(
         new TxAbortedEvent(context.globalTxId(), context.localTxId(), parentTxId, compensationMethod, throwable));
   }
-  
-  public void sendSagaEndEvent() {
-    sender.send(new SagaEndedEvent(context.globalTxId(), context.localTxId()));
-  }
+
 }
diff --git a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/SagaEndAspect.java b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/SagaEndAspect.java
new file mode 100644
index 0000000..14e1041
--- /dev/null
+++ b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/SagaEndAspect.java
@@ -0,0 +1,75 @@
+/*
+ * 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.pack.omega.transaction;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.Method;
+
+import org.apache.servicecomb.pack.omega.context.OmegaContext;
+import org.apache.servicecomb.pack.omega.context.annotations.SagaEnd;
+import org.apache.servicecomb.pack.omega.context.annotations.SagaStart;
+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;
+import org.springframework.core.annotation.Order;
+
+@Aspect
+@Order(value = 100)
+public class SagaEndAspect {
+  private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+  private final OmegaContext context;
+  private final SagaMessageSender sender;
+
+  public SagaEndAspect(SagaMessageSender sender, OmegaContext context) {
+    this.sender = sender;
+    this.context = context;
+  }
+
+  @Around("execution(@org.apache.servicecomb.pack.omega.context.annotations.SagaEnded * *(..)) && @annotation(sagaEnd)")
+  Object advise(ProceedingJoinPoint joinPoint, SagaEnd sagaEnd) throws Throwable {
+      Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
+      try {
+        Object result = joinPoint.proceed();
+        sendSagaEndedEvent();
+        return result;
+      } catch (Throwable throwable) {
+        // Don't check the OmegaException here.
+        if (!(throwable instanceof OmegaException)) {
+          LOG.error("Transaction {} failed.", context.globalTxId());
+          sendSagaAbortedEvent(method.toString(), throwable);
+        }
+        throw throwable;
+      }
+      finally {
+        context.clear();
+      }
+  }
+
+  private void sendSagaEndedEvent() {
+    // TODO need to check the parentID setting
+    sender.send(new SagaEndedEvent(context.globalTxId(), context.localTxId()));
+  }
+
+  private void sendSagaAbortedEvent(String methodName, Throwable throwable) {
+    // TODO need to check the parentID setting
+    sender.send(new SagaAbortedEvent(context.globalTxId(), context.localTxId(), null, methodName, throwable));
+  }
+
+}
diff --git a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/TransactionAspect.java b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/TransactionAspect.java
index 5729973..b79e565 100644
--- a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/TransactionAspect.java
+++ b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/TransactionAspect.java
@@ -29,8 +29,10 @@ import org.aspectj.lang.annotation.Aspect;
 import org.aspectj.lang.reflect.MethodSignature;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.core.annotation.Order;
 
 @Aspect
+@Order(value=10)
 public class TransactionAspect extends TransactionContextHelper {
 
   private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
diff --git a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/annotations/Compensable.java b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/annotations/Compensable.java
index 0272d29..9186639 100644
--- a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/annotations/Compensable.java
+++ b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/annotations/Compensable.java
@@ -73,10 +73,4 @@ public @interface Compensable {
    */
   int timeout() default 0;
 
-  /**
-   * Sending out SagaEnd event to Alpha once the SagaStart annotated method is finished without any error.
-   * Default value is false, which means Omega never send out the SagaEnd event to Alpha once the annotated method is finished.
-   * value is true, means this method is last compensable method need to be called, Omega will send SagaEnd event to Alpha once the method is finished.
-   */
-  boolean sendingSagaEnd() default false;
 }
diff --git a/omega/omega-transaction/src/test/java/org/apache/servicecomb/pack/omega/transaction/SagaEndAspectTest.java b/omega/omega-transaction/src/test/java/org/apache/servicecomb/pack/omega/transaction/SagaEndAspectTest.java
new file mode 100644
index 0000000..6a37f72
--- /dev/null
+++ b/omega/omega-transaction/src/test/java/org/apache/servicecomb/pack/omega/transaction/SagaEndAspectTest.java
@@ -0,0 +1,137 @@
+/*
+ * 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.pack.omega.transaction;
+
+import static com.seanyinx.github.unit.scaffolding.AssertUtils.expectFailing;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.servicecomb.pack.common.EventType;
+import org.apache.servicecomb.pack.omega.context.IdGenerator;
+import org.apache.servicecomb.pack.omega.context.OmegaContext;
+import org.apache.servicecomb.pack.omega.context.annotations.SagaEnd;
+import org.apache.servicecomb.pack.omega.context.annotations.SagaStart;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class SagaEndAspectTest {
+  private final List<TxEvent> messages = new ArrayList<>();
+  private final String globalTxId = UUID.randomUUID().toString();
+
+  private final SagaMessageSender sender = new SagaMessageSender() {
+    @Override
+    public void onConnected() {
+    }
+
+    @Override
+    public void onDisconnected() {
+    }
+
+    @Override
+    public void close() {
+    }
+
+    @Override
+    public String target() {
+      return "UNKNOWN";
+    }
+
+    @Override
+    public AlphaResponse send(TxEvent event) {
+      messages.add(event);
+      return new AlphaResponse(false);
+    }
+  };
+  private final ProceedingJoinPoint joinPoint = Mockito.mock(ProceedingJoinPoint.class);
+  private final MethodSignature methodSignature = Mockito.mock(MethodSignature.class);
+
+  @SuppressWarnings("unchecked")
+  private final IdGenerator<String> idGenerator = Mockito.mock(IdGenerator.class);
+  private final SagaEnd sagaEnd = Mockito.mock(SagaEnd.class);
+
+  private final OmegaContext omegaContext = Mockito.mock(OmegaContext.class);
+  private SagaEndAspect aspect;
+
+  @Before
+  public void setUp() throws Exception {
+    when(omegaContext.globalTxId()).thenReturn(globalTxId);
+    when(omegaContext.localTxId()).thenReturn(globalTxId);
+    when(joinPoint.getSignature()).thenReturn(methodSignature);
+    when(methodSignature.getMethod()).thenReturn(this.getClass().getDeclaredMethod("doNothing"));
+  }
+
+  @Test
+  public void sagaEndWithoutError() throws Throwable {
+    aspect = new SagaEndAspect(sender, omegaContext);
+    aspect.advise(joinPoint, sagaEnd);
+    assertThat(messages.size(), is(1));
+    TxEvent endedEvent = messages.get(0);
+
+    assertThat(endedEvent.globalTxId(), is(globalTxId));
+    assertThat(endedEvent.localTxId(), is(globalTxId));
+    assertThat(endedEvent.parentTxId(), is(nullValue()));
+    assertThat(endedEvent.type(), is(EventType.SagaEndedEvent));
+
+    verify(omegaContext).clear();
+  }
+
+
+
+  @Test
+  public void sagaEndWithErrors() throws Throwable {
+
+    aspect = new SagaEndAspect(sender, omegaContext);
+    RuntimeException oops = new RuntimeException("oops");
+
+    when(joinPoint.proceed()).thenThrow(oops);
+
+    try {
+      aspect.advise(joinPoint, sagaEnd);
+      expectFailing(RuntimeException.class);
+    } catch (RuntimeException e) {
+      assertThat(e, is(oops));
+    }
+
+    assertThat(messages.size(), is(1));
+    TxEvent event = messages.get(0);
+
+    assertThat(event.globalTxId(), is(globalTxId));
+    assertThat(event.localTxId(), is(globalTxId));
+    assertThat(event.parentTxId(), is(nullValue()));
+    assertThat(event.type(), is(EventType.SagaAbortedEvent));
+
+    verify(omegaContext).clear();
+  }
+
+
+
+
+  private String doNothing() {
+    return "doNothing";
+  }
+}
diff --git a/omega/omega-transaction/src/test/java/org/apache/servicecomb/pack/omega/transaction/TransactionAspectTest.java b/omega/omega-transaction/src/test/java/org/apache/servicecomb/pack/omega/transaction/TransactionAspectTest.java
index 3de4013..3c60789 100644
--- a/omega/omega-transaction/src/test/java/org/apache/servicecomb/pack/omega/transaction/TransactionAspectTest.java
+++ b/omega/omega-transaction/src/test/java/org/apache/servicecomb/pack/omega/transaction/TransactionAspectTest.java
@@ -111,35 +111,6 @@ public class TransactionAspectTest {
   }
 
   @Test
-  public void sendingSageEndEvent() throws Throwable {
-    when(compensable.sendingSagaEnd()).thenReturn(true);
-    aspect.advise(joinPoint, compensable);
-    assertThat(messages.size(), is(3));
-
-    TxEvent startedEvent = messages.get(0);
-
-    assertThat(startedEvent.globalTxId(), is(globalTxId));
-    assertThat(startedEvent.localTxId(), is(newLocalTxId));
-    assertThat(startedEvent.parentTxId(), is(localTxId));
-    assertThat(startedEvent.type(), is(EventType.TxStartedEvent));
-    assertThat(startedEvent.retries(), is(0));
-    assertThat(startedEvent.retryMethod().isEmpty(), is(true));
-
-    TxEvent endedEvent = messages.get(1);
-
-    assertThat(endedEvent.globalTxId(), is(globalTxId));
-    assertThat(endedEvent.localTxId(), is(newLocalTxId));
-    assertThat(endedEvent.parentTxId(), is(localTxId));
-    assertThat(endedEvent.type(), is(EventType.TxEndedEvent));
-
-    TxEvent sagaEndEvent = messages.get(2);
-    assertThat(sagaEndEvent.globalTxId(), is(globalTxId));
-    assertNull(sagaEndEvent.parentTxId());
-    assertThat(sagaEndEvent.localTxId(), is(newLocalTxId));
-    assertThat(sagaEndEvent.type(), is(EventType.SagaEndedEvent));
-  }
-
-  @Test
   public void setNewLocalTxIdCompensableWithTransactionContext() throws Throwable {
     // setup the argument class
     when(joinPoint.getArgs()).thenReturn(new Object[]{transactionContextProperties});


[servicecomb-pack] 03/06: SCB-1386 using autoClose attribute in SagaStart

Posted by ni...@apache.org.
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/servicecomb-pack.git

commit a47e27c9bf3ba6a7d042b50679d83ab373992f47
Author: Willem Jiang <wi...@gmail.com>
AuthorDate: Wed Jul 31 10:02:54 2019 +0800

    SCB-1386 using autoClose attribute in SagaStart
---
 .../servicecomb/pack/omega/context/annotations/SagaStart.java     | 8 ++++----
 .../transaction/wrapper/SagaStartAnnotationProcessorWrapper.java  | 2 +-
 .../servicecomb/pack/omega/transaction/SagaStartAspectTest.java   | 4 ++--
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/annotations/SagaStart.java b/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/annotations/SagaStart.java
index 7517bd4..09a3409 100644
--- a/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/annotations/SagaStart.java
+++ b/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/annotations/SagaStart.java
@@ -39,9 +39,9 @@ public @interface SagaStart {
   int timeout() default 0;
 
   /**
-   * Sending out SagaEnd event to Alpha once the SagaStart annotated method is finished without any error.
-   * Default value is true, which means Omega sends out the SagaEnd event to Alpha once the annotated method is finished.
-   * Value is false, which means Omega never sends out the SagaEnd event to Alpha once the annotated method is finished.
+   * Sending out SagaEnded event to Alpha once the SagaStart annotated method is finished without any error.
+   * Default value is true, which means Omega sends out the SagaEnded event to Alpha once the annotated method is finished.
+   * Value is false, which means Omega never sends out the SagaEnded event to Alpha once the annotated method is finished.
    */
-  boolean sendingSagaEnd() default true;
+  boolean autoClose() default true;
 }
diff --git a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/wrapper/SagaStartAnnotationProcessorWrapper.java b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/wrapper/SagaStartAnnotationProcessorWrapper.java
index f71e507..528171e 100644
--- a/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/wrapper/SagaStartAnnotationProcessorWrapper.java
+++ b/omega/omega-transaction/src/main/java/org/apache/servicecomb/pack/omega/transaction/wrapper/SagaStartAnnotationProcessorWrapper.java
@@ -45,7 +45,7 @@ public class SagaStartAnnotationProcessorWrapper {
     LOG.debug("Initialized context {} before execution of method {}", context, method.toString());
     try {
       Object result = joinPoint.proceed();
-      if (sagaStart.sendingSagaEnd()) {
+      if (sagaStart.autoClose()) {
         sagaStartAnnotationProcessor.postIntercept(context.globalTxId());
         LOG.debug("Transaction with context {} has finished.", context);
       } else {
diff --git a/omega/omega-transaction/src/test/java/org/apache/servicecomb/pack/omega/transaction/SagaStartAspectTest.java b/omega/omega-transaction/src/test/java/org/apache/servicecomb/pack/omega/transaction/SagaStartAspectTest.java
index c03a594..66b55a8 100644
--- a/omega/omega-transaction/src/test/java/org/apache/servicecomb/pack/omega/transaction/SagaStartAspectTest.java
+++ b/omega/omega-transaction/src/test/java/org/apache/servicecomb/pack/omega/transaction/SagaStartAspectTest.java
@@ -81,7 +81,7 @@ public class SagaStartAspectTest {
     when(joinPoint.getSignature()).thenReturn(methodSignature);
     when(methodSignature.getMethod()).thenReturn(this.getClass().getDeclaredMethod("doNothing"));
     // setup the default value of SagaStart
-    when(sagaStart.sendingSagaEnd()).thenReturn(true);
+    when(sagaStart.autoClose()).thenReturn(true);
   }
 
   @Test
@@ -110,7 +110,7 @@ public class SagaStartAspectTest {
 
   @Test
   public void dontSendingSagaEndMessage() throws Throwable {
-    when(sagaStart.sendingSagaEnd()).thenReturn(false);
+    when(sagaStart.autoClose()).thenReturn(false);
     omegaContext = new OmegaContext(idGenerator);
     aspect = new SagaStartAspect(sender, omegaContext);
 


[servicecomb-pack] 06/06: SCB-1386 Added some comments on the SagaEnd annotation.

Posted by ni...@apache.org.
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/servicecomb-pack.git

commit b8abd1a21aa39ca3c628ae1d7b6078e2d773fff6
Author: Willem Jiang <wi...@gmail.com>
AuthorDate: Thu Aug 1 22:23:04 2019 +0800

    SCB-1386 Added some comments on the SagaEnd annotation.
---
 .../org/apache/servicecomb/pack/omega/context/annotations/SagaEnd.java | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/annotations/SagaEnd.java b/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/annotations/SagaEnd.java
index 23c3666..18df029 100644
--- a/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/annotations/SagaEnd.java
+++ b/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/annotations/SagaEnd.java
@@ -18,6 +18,9 @@ package org.apache.servicecomb.pack.omega.context.annotations;
 
 /**
  * Indicates once the annotated method is finished, it will end a saga.
+ * Please note:
+ *  You need to set the attribute of @SagaStart autoClose to be falseļ¼Œ
+ *  then you can end the Saga transaction as you want with this SagaEnd annotation.
  */
 public class SagaEnd {