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/07/22 11:20:21 UTC
[servicecomb-pack] 01/05: SCB-1385 provide a common way to pass the
GID and LID
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 2532988411da51e38cfdb7129485d5cbad63aee3
Author: Willem Jiang <wi...@gmail.com>
AuthorDate: Fri Jul 19 19:37:22 2019 +0800
SCB-1385 provide a common way to pass the GID and LID
---
.../pack/omega/context/OmegaContext.java | 4 ++
.../pack/omega/context/TransactionContext.java | 46 +++++++++++++++++++
.../omega/context/TransactionContextWrapper.java | 25 +++++++++++
.../pack/omega/transaction/TransactionAspect.java | 22 +++++++++
.../omega/transaction/TransactionAspectTest.java | 52 ++++++++++++++++++++++
5 files changed, 149 insertions(+)
diff --git a/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/OmegaContext.java b/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/OmegaContext.java
index 96e54bd..660b923 100644
--- a/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/OmegaContext.java
+++ b/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/OmegaContext.java
@@ -71,6 +71,10 @@ public class OmegaContext {
return alphaFeatureAkkaEnabled;
}
+ public TransactionContext getTransactionContext() {
+ return new TransactionContext(globalTxId(), localTxId());
+ }
+
public void clear() {
globalTxId.remove();
localTxId.remove();
diff --git a/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/TransactionContext.java b/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/TransactionContext.java
new file mode 100644
index 0000000..48bd370
--- /dev/null
+++ b/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/TransactionContext.java
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+/**
+ * This class is holding the Transaction related context which could be use in customer code
+ */
+public class TransactionContext {
+ private String globalTxId;
+ private String localTxId;
+
+ public TransactionContext(String globalTxId, String localTxId) {
+ this.globalTxId = globalTxId;
+ this.localTxId = localTxId;
+ }
+
+ public String globalTxId() {
+ return globalTxId;
+ }
+
+ public void setGlobalTxId(String globalTxId) {
+ this.globalTxId = globalTxId;
+ }
+
+ public String localTxId() {
+ return localTxId;
+ }
+
+ public void setLocalTxId(String localTxId) {
+ this.localTxId = localTxId;
+ }
+}
diff --git a/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/TransactionContextWrapper.java b/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/TransactionContextWrapper.java
new file mode 100644
index 0000000..ccfe099
--- /dev/null
+++ b/omega/omega-context/src/main/java/org/apache/servicecomb/pack/omega/context/TransactionContextWrapper.java
@@ -0,0 +1,25 @@
+/*
+ * 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;
+
+/**
+ * Once the user business class implement this TransactionContextWrapper, Omega could extract the TransactionContext instance
+ * out of the business class, and set up the OmegaContext before calling sub transaction method.
+ */
+public interface TransactionContextWrapper {
+ TransactionContext getTransactionContext();
+}
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 5e57ee7..fa7bbf4 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
@@ -21,6 +21,8 @@ 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.TransactionContext;
+import org.apache.servicecomb.pack.omega.context.TransactionContextWrapper;
import org.apache.servicecomb.pack.omega.transaction.annotations.Compensable;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
@@ -46,6 +48,15 @@ public class TransactionAspect {
@Around("execution(@org.apache.servicecomb.pack.omega.transaction.annotations.Compensable * *(..)) && @annotation(compensable)")
Object advise(ProceedingJoinPoint joinPoint, Compensable compensable) throws Throwable {
Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
+ // just check if we need to setup the transaction context information first
+ TransactionContext transactionContext = getTransactionContextFromArgs(joinPoint.getArgs());
+ if (transactionContext != null) {
+ LOG.debug("Updated context {} for globalTxId:{} and localTxId:{}", context,
+ transactionContext.globalTxId(), transactionContext.localTxId());
+ context.setGlobalTxId(transactionContext.globalTxId());
+ context.setLocalTxId(transactionContext.localTxId());
+ }
+
String localTxId = context.localTxId();
context.newLocalTxId();
LOG.debug("Updated context {} for compensable method {} ", context, method.toString());
@@ -59,4 +70,15 @@ public class TransactionAspect {
LOG.debug("Restored context back to {}", context);
}
}
+
+ TransactionContext getTransactionContextFromArgs(Object[] args) {
+ if (args != null) {
+ for (Object arg : args) {
+ if (arg instanceof TransactionContextWrapper) {
+ return ((TransactionContextWrapper) arg).getTransactionContext();
+ }
+ }
+ }
+ return null;
+ }
}
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 eb82080..17a5aa3 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
@@ -21,7 +21,9 @@ import static com.seanyinx.github.unit.scaffolding.AssertUtils.expectFailing;
import static org.hamcrest.core.AnyOf.anyOf;
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.ArgumentMatchers.isNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -37,6 +39,8 @@ 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.TransactionContext;
+import org.apache.servicecomb.pack.omega.context.TransactionContextWrapper;
import org.apache.servicecomb.pack.omega.transaction.annotations.Compensable;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
@@ -52,6 +56,9 @@ public class TransactionAspectTest {
private final String localTxId = UUID.randomUUID().toString();
private final String newLocalTxId = UUID.randomUUID().toString();
+ private final String transactionGloablTxId = UUID.randomUUID().toString();
+ private final String transactionLocalTxId = UUID.randomUUID().toString();
+
private final SagaMessageSender sender = new SagaMessageSender() {
@Override
public void onConnected() {
@@ -86,6 +93,9 @@ public class TransactionAspectTest {
private final OmegaContext omegaContext = new OmegaContext(idGenerator);
private final TransactionAspect aspect = new TransactionAspect(sender, omegaContext);
+ private final TransactionContext tx = mock(TransactionContext.class);
+ private final TransactionContextWrapper wrapper = mock(TransactionContextWrapper.class);
+
@Before
public void setUp() throws Exception {
when(idGenerator.nextId()).thenReturn(newLocalTxId);
@@ -98,6 +108,48 @@ public class TransactionAspectTest {
omegaContext.setGlobalTxId(globalTxId);
omegaContext.setLocalTxId(localTxId);
+
+ when(wrapper.getTransactionContext()).thenReturn(tx);
+ when(tx.globalTxId()).thenReturn(transactionGloablTxId);
+ when(tx.localTxId()).thenReturn(transactionLocalTxId);
+ }
+
+ @Test
+ public void testGetTransactionContextFromArgs() throws Throwable {
+
+ TransactionContext result = aspect.getTransactionContextFromArgs(new Object[]{tx,wrapper});
+ assertThat(result, is(tx));
+
+ result = aspect.getTransactionContextFromArgs(new Object[]{});
+ assertNull(result);
+
+ result = aspect.getTransactionContextFromArgs(new Object[]{tx});
+ assertNull(result);
+ }
+
+ @Test
+ public void setNewLocalTxIdCompensableWithTransactionContext() throws Throwable {
+ // setup the argument class
+ when(joinPoint.getArgs()).thenReturn(new Object[]{wrapper});
+ aspect.advise(joinPoint, compensable);
+ TxEvent startedEvent = messages.get(0);
+
+ assertThat(startedEvent.globalTxId(), is(transactionGloablTxId));
+ assertThat(startedEvent.localTxId(), is(newLocalTxId));
+ assertThat(startedEvent.parentTxId(), is(transactionLocalTxId));
+ 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(transactionGloablTxId));
+ assertThat(endedEvent.localTxId(), is(newLocalTxId));
+ assertThat(endedEvent.parentTxId(), is(transactionLocalTxId));
+ assertThat(endedEvent.type(), is(EventType.TxEndedEvent));
+
+ assertThat(omegaContext.globalTxId(), is(transactionGloablTxId));
+ assertThat(omegaContext.localTxId(), is(transactionLocalTxId));
}
@Test