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 5b0be4b28b0e26a56271bfc7b36c4d40b5c65985 Author: seanyinx <sean....@huawei.com> AuthorDate: Wed Jan 10 15:39:20 2018 +0800 SCB-212 made each @Compensable as a new sub-transaction Signed-off-by: seanyinx <sean....@huawei.com> --- .../integration/pack/tests/GreetingController.java | 13 ++ .../saga/integration/pack/tests/PackIT.java | 184 +++++++++++++-------- .../spring/TransactionAspectConfig.java | 9 + .../spring/TransactionInterceptionTest.java | 74 +++++---- .../transaction/SagaStartAnnotationProcessor.java | 12 +- .../saga/omega/transaction/SagaStartAspect.java | 60 +++++++ .../saga/omega/transaction/TransactionAspect.java | 46 ++---- .../SagaStartAnnotationProcessorTest.java | 11 +- .../omega/transaction/SagaStartAspectTest.java | 124 ++++++++++++++ .../omega/transaction/TransactionAspectTest.java | 124 ++++++++++++++ .../TransactionHandlerInterceptor.java | 16 +- .../TransactionHandlerInterceptorTest.java | 8 +- 12 files changed, 524 insertions(+), 157 deletions(-) diff --git a/integration-tests/pack-tests/src/test/java/org/apache/servicecomb/saga/integration/pack/tests/GreetingController.java b/integration-tests/pack-tests/src/test/java/org/apache/servicecomb/saga/integration/pack/tests/GreetingController.java index 3c7c095..2bdd587 100644 --- a/integration-tests/pack-tests/src/test/java/org/apache/servicecomb/saga/integration/pack/tests/GreetingController.java +++ b/integration-tests/pack-tests/src/test/java/org/apache/servicecomb/saga/integration/pack/tests/GreetingController.java @@ -18,6 +18,7 @@ package org.apache.servicecomb.saga.integration.pack.tests; import org.apache.servicecomb.saga.omega.context.annotations.SagaStart; +import org.apache.servicecomb.saga.omega.transaction.annotations.Compensable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; @@ -64,4 +65,16 @@ public class GreetingController { ResponseEntity<String> rude(@RequestParam String name) { return ResponseEntity.ok(greetingService.beingRude(name)); } + + @SagaStart + @Compensable(compensationMethod = "goodNight") + @GetMapping("/goodMorning") + ResponseEntity<String> goodMorning(@RequestParam String name) { + String bonjour = restTemplate.getForObject("http://localhost:8080/bonjour?name={name}", String.class, name); + return ResponseEntity.ok("Good morning, " + bonjour); + } + + ResponseEntity<String> goodNight(@RequestParam String name) { + return ResponseEntity.ok("Good night, " + name); + } } diff --git a/integration-tests/pack-tests/src/test/java/org/apache/servicecomb/saga/integration/pack/tests/PackIT.java b/integration-tests/pack-tests/src/test/java/org/apache/servicecomb/saga/integration/pack/tests/PackIT.java index 56092be..7ed1b88 100644 --- a/integration-tests/pack-tests/src/test/java/org/apache/servicecomb/saga/integration/pack/tests/PackIT.java +++ b/integration-tests/pack-tests/src/test/java/org/apache/servicecomb/saga/integration/pack/tests/PackIT.java @@ -48,7 +48,6 @@ import org.springframework.test.context.junit4.SpringRunner; properties = {"server.port=8080", "spring.application.name=greeting-service"}) public class PackIT { private static final String serviceName = "greeting-service"; - private final String globalTxId = UUID.randomUUID().toString(); @Autowired private TestRestTemplate restTemplate; @@ -84,47 +83,47 @@ public class PackIT { assertThat(envelopes.size(), is(6)); - TxEventEnvelope sagaStartedEventEnvelope = envelopes.get(0); - assertThat(sagaStartedEventEnvelope.type(), is("SagaStartedEvent")); - assertThat(sagaStartedEventEnvelope.localTxId(), is(notNullValue())); - assertThat(sagaStartedEventEnvelope.parentTxId(), is(nullValue())); - assertThat(sagaStartedEventEnvelope.serviceName(), is(serviceName)); - assertThat(sagaStartedEventEnvelope.instanceId(), is(notNullValue())); - - TxEventEnvelope txStartedEventEnvelope1 = envelopes.get(1); - assertThat(txStartedEventEnvelope1.type(), is("TxStartedEvent")); - assertThat(txStartedEventEnvelope1.localTxId(), is(notNullValue())); - assertThat(txStartedEventEnvelope1.parentTxId(), is(sagaStartedEventEnvelope.localTxId())); - assertThat(txStartedEventEnvelope1.serviceName(), is(serviceName)); - assertThat(txStartedEventEnvelope1.instanceId(), is(sagaStartedEventEnvelope.instanceId())); - - TxEventEnvelope txEndedEventEnvelope1 = envelopes.get(2); - assertThat(txEndedEventEnvelope1.type(), is("TxEndedEvent")); - assertThat(txEndedEventEnvelope1.localTxId(), is(txStartedEventEnvelope1.localTxId())); - assertThat(txEndedEventEnvelope1.parentTxId(), is(sagaStartedEventEnvelope.localTxId())); - assertThat(txEndedEventEnvelope1.serviceName(), is(serviceName)); - assertThat(txEndedEventEnvelope1.instanceId(), is(txStartedEventEnvelope1.instanceId())); - - TxEventEnvelope txStartedEventEnvelope2 = envelopes.get(3); - assertThat(txStartedEventEnvelope2.type(), is("TxStartedEvent")); - assertThat(txStartedEventEnvelope2.localTxId(), is(notNullValue())); - assertThat(txStartedEventEnvelope2.parentTxId(), is(txStartedEventEnvelope1.localTxId())); - assertThat(txStartedEventEnvelope2.serviceName(), is(serviceName)); - assertThat(txStartedEventEnvelope2.instanceId(), is(notNullValue())); - - TxEventEnvelope txEndedEventEnvelope2 = envelopes.get(4); - assertThat(txEndedEventEnvelope2.type(), is("TxEndedEvent")); - assertThat(txEndedEventEnvelope2.localTxId(), is(txStartedEventEnvelope2.localTxId())); - assertThat(txEndedEventEnvelope2.parentTxId(), is(txStartedEventEnvelope1.localTxId())); - assertThat(txEndedEventEnvelope2.serviceName(), is(serviceName)); - assertThat(txEndedEventEnvelope2.instanceId(), is(txStartedEventEnvelope2.instanceId())); - - TxEventEnvelope sagaEndedEventEnvelope = envelopes.get(5); - assertThat(sagaEndedEventEnvelope.type(), is("SagaEndedEvent")); - assertThat(sagaEndedEventEnvelope.localTxId(), is(sagaStartedEventEnvelope.localTxId())); - assertThat(sagaEndedEventEnvelope.parentTxId(), is(nullValue())); - assertThat(sagaEndedEventEnvelope.serviceName(), is(serviceName)); - assertThat(sagaEndedEventEnvelope.instanceId(), is(notNullValue())); + TxEventEnvelope sagaStartedEvent = envelopes.get(0); + assertThat(sagaStartedEvent.type(), is("SagaStartedEvent")); + assertThat(sagaStartedEvent.localTxId(), is(globalTxId)); + assertThat(sagaStartedEvent.parentTxId(), is(nullValue())); + assertThat(sagaStartedEvent.serviceName(), is(serviceName)); + assertThat(sagaStartedEvent.instanceId(), is(notNullValue())); + + TxEventEnvelope txStartedEvent1 = envelopes.get(1); + assertThat(txStartedEvent1.type(), is("TxStartedEvent")); + assertThat(txStartedEvent1.localTxId(), is(notNullValue())); + assertThat(txStartedEvent1.parentTxId(), is(globalTxId)); + assertThat(txStartedEvent1.serviceName(), is(serviceName)); + assertThat(txStartedEvent1.instanceId(), is(sagaStartedEvent.instanceId())); + + TxEventEnvelope txEndedEvent1 = envelopes.get(2); + assertThat(txEndedEvent1.type(), is("TxEndedEvent")); + assertThat(txEndedEvent1.localTxId(), is(txStartedEvent1.localTxId())); + assertThat(txEndedEvent1.parentTxId(), is(globalTxId)); + assertThat(txEndedEvent1.serviceName(), is(serviceName)); + assertThat(txEndedEvent1.instanceId(), is(txStartedEvent1.instanceId())); + + TxEventEnvelope txStartedEvent2 = envelopes.get(3); + assertThat(txStartedEvent2.type(), is("TxStartedEvent")); + assertThat(txStartedEvent2.localTxId(), is(notNullValue())); + assertThat(txStartedEvent2.parentTxId(), is(globalTxId)); + assertThat(txStartedEvent2.serviceName(), is(serviceName)); + assertThat(txStartedEvent2.instanceId(), is(notNullValue())); + + TxEventEnvelope txEndedEvent2 = envelopes.get(4); + assertThat(txEndedEvent2.type(), is("TxEndedEvent")); + assertThat(txEndedEvent2.localTxId(), is(txStartedEvent2.localTxId())); + assertThat(txEndedEvent2.parentTxId(), is(globalTxId)); + assertThat(txEndedEvent2.serviceName(), is(serviceName)); + assertThat(txEndedEvent2.instanceId(), is(txStartedEvent2.instanceId())); + + TxEventEnvelope sagaEndedEvent = envelopes.get(5); + assertThat(sagaEndedEvent.type(), is("SagaEndedEvent")); + assertThat(sagaEndedEvent.localTxId(), is(globalTxId)); + assertThat(sagaEndedEvent.parentTxId(), is(nullValue())); + assertThat(sagaEndedEvent.serviceName(), is(serviceName)); + assertThat(sagaEndedEvent.instanceId(), is(notNullValue())); assertThat(compensatedMessages.isEmpty(), is(true)); } @@ -146,36 +145,37 @@ public class PackIT { List<TxEventEnvelope> envelopes = repository.findByGlobalTxIdOrderByCreationTime(globalTxId); assertThat(envelopes.size(), is(8)); - TxEventEnvelope sagaStartedEventEnvelope = envelopes.get(0); - assertThat(sagaStartedEventEnvelope.type(), is("SagaStartedEvent")); + TxEventEnvelope sagaStartedEvent = envelopes.get(0); + assertThat(sagaStartedEvent.type(), is("SagaStartedEvent")); - TxEventEnvelope txStartedEventEnvelope1 = envelopes.get(1); - assertThat(txStartedEventEnvelope1.type(), is("TxStartedEvent")); + TxEventEnvelope txStartedEvent1 = envelopes.get(1); + assertThat(txStartedEvent1.type(), is("TxStartedEvent")); assertThat(envelopes.get(2).type(), is("TxEndedEvent")); - TxEventEnvelope txStartedEventEnvelope2 = envelopes.get(3); - assertThat(txStartedEventEnvelope2.type(), is("TxStartedEvent")); - - TxEventEnvelope txAbortedEventEnvelope = envelopes.get(4); - assertThat(txAbortedEventEnvelope.type(), is("TxAbortedEvent")); - assertThat(txAbortedEventEnvelope.localTxId(), is(txStartedEventEnvelope2.localTxId())); - assertThat(txAbortedEventEnvelope.parentTxId(), is(txStartedEventEnvelope1.localTxId())); - assertThat(txAbortedEventEnvelope.serviceName(), is(serviceName)); - assertThat(txAbortedEventEnvelope.instanceId(), is(txStartedEventEnvelope2.instanceId())); - - TxEventEnvelope txCompensatedEventEnvelope1 = envelopes.get(5); - assertThat(txCompensatedEventEnvelope1.type(), is("TxCompensatedEvent")); - assertThat(txCompensatedEventEnvelope1.localTxId(), is(txStartedEventEnvelope1.localTxId())); - assertThat(txCompensatedEventEnvelope1.parentTxId(), is(sagaStartedEventEnvelope.localTxId())); - assertThat(txCompensatedEventEnvelope1.serviceName(), is(serviceName)); - assertThat(txCompensatedEventEnvelope1.instanceId(), is(txStartedEventEnvelope1.instanceId())); - - TxEventEnvelope txCompensatedEventEnvelope2 = envelopes.get(6); - assertThat(txCompensatedEventEnvelope2.type(), is("TxCompensatedEvent")); - assertThat(txCompensatedEventEnvelope2.localTxId(), is(txStartedEventEnvelope2.localTxId())); - assertThat(txCompensatedEventEnvelope2.parentTxId(), is(txStartedEventEnvelope1.localTxId())); - assertThat(txCompensatedEventEnvelope2.serviceName(), is(serviceName)); - assertThat(txCompensatedEventEnvelope2.instanceId(), is(txStartedEventEnvelope2.instanceId())); + TxEventEnvelope txStartedEvent2 = envelopes.get(3); + assertThat(txStartedEvent2.type(), is("TxStartedEvent")); + + TxEventEnvelope txAbortedEvent = envelopes.get(4); + assertThat(txAbortedEvent.type(), is("TxAbortedEvent")); + assertThat(txAbortedEvent.localTxId(), is(txStartedEvent2.localTxId())); + assertThat(txAbortedEvent.parentTxId(), is(globalTxId)); + assertThat(txAbortedEvent.serviceName(), is(serviceName)); + assertThat(txAbortedEvent.instanceId(), is(txStartedEvent2.instanceId())); + + // TODO: 2018/1/9 compensation shall be done in reverse order + TxEventEnvelope txCompensatedEvent1 = envelopes.get(5); + assertThat(txCompensatedEvent1.type(), is("TxCompensatedEvent")); + assertThat(txCompensatedEvent1.localTxId(), is(txStartedEvent1.localTxId())); + assertThat(txCompensatedEvent1.parentTxId(), is(globalTxId)); + assertThat(txCompensatedEvent1.serviceName(), is(serviceName)); + assertThat(txCompensatedEvent1.instanceId(), is(txStartedEvent1.instanceId())); + + TxEventEnvelope txCompensatedEvent2 = envelopes.get(6); + assertThat(txCompensatedEvent2.type(), is("TxCompensatedEvent")); + assertThat(txCompensatedEvent2.localTxId(), is(txStartedEvent2.localTxId())); + assertThat(txCompensatedEvent2.parentTxId(), is(globalTxId)); + assertThat(txCompensatedEvent2.serviceName(), is(serviceName)); + assertThat(txCompensatedEvent2.instanceId(), is(txStartedEvent2.instanceId())); assertThat(envelopes.get(7).type(), is("SagaEndedEvent")); @@ -183,4 +183,50 @@ public class PackIT { "Goodbye, " + TRESPASSER, "My bad, please take the window instead, " + TRESPASSER)); } + + @Test(timeout = 5000) + public void updatesEmbeddedTxStateToAlpha() throws Exception { + ResponseEntity<String> entity = restTemplate.getForEntity("/goodMorning?name={name}", + String.class, + "mike"); + + assertThat(entity.getStatusCode(), is(OK)); + assertThat(entity.getBody(), is("Good morning, Bonjour, mike")); + + List<String> distinctGlobalTxIds = repository.findDistinctGlobalTxId(); + assertThat(distinctGlobalTxIds.size(), is(1)); + + String globalTxId = distinctGlobalTxIds.get(0); + List<TxEventEnvelope> envelopes = repository.findByGlobalTxIdOrderByCreationTime(globalTxId); + + assertThat(envelopes.size(), is(6)); + + TxEventEnvelope sagaStartedEvent = envelopes.get(0); + assertThat(sagaStartedEvent.type(), is("SagaStartedEvent")); + + TxEventEnvelope txStartedEvent1 = envelopes.get(1); + assertThat(txStartedEvent1.type(), is("TxStartedEvent")); + assertThat(txStartedEvent1.localTxId(), is(notNullValue())); + assertThat(txStartedEvent1.parentTxId(), is(globalTxId)); + + TxEventEnvelope txStartedEvent2 = envelopes.get(2); + assertThat(txStartedEvent2.type(), is("TxStartedEvent")); + assertThat(txStartedEvent2.localTxId(), is(notNullValue())); + assertThat(txStartedEvent2.parentTxId(), is(txStartedEvent1.localTxId())); + + TxEventEnvelope txEndedEvent2 = envelopes.get(3); + assertThat(txEndedEvent2.type(), is("TxEndedEvent")); + assertThat(txEndedEvent2.localTxId(), is(txStartedEvent2.localTxId())); + assertThat(txEndedEvent2.parentTxId(), is(txStartedEvent1.localTxId())); + + TxEventEnvelope txEndedEvent1 = envelopes.get(4); + assertThat(txEndedEvent1.type(), is("TxEndedEvent")); + assertThat(txEndedEvent1.localTxId(), is(txStartedEvent1.localTxId())); + assertThat(txEndedEvent1.parentTxId(), is(globalTxId)); + + TxEventEnvelope sagaEndedEvent = envelopes.get(5); + assertThat(sagaEndedEvent.type(), is("SagaEndedEvent")); + + assertThat(compensatedMessages.isEmpty(), is(true)); + } } 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 dc88bbd..5358db5 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 @@ -22,10 +22,12 @@ import org.apache.servicecomb.saga.omega.context.OmegaContext; import org.apache.servicecomb.saga.omega.transaction.CompensationMessageHandler; import org.apache.servicecomb.saga.omega.transaction.MessageHandler; import org.apache.servicecomb.saga.omega.transaction.MessageSender; +import org.apache.servicecomb.saga.omega.transaction.SagaStartAspect; import org.apache.servicecomb.saga.omega.transaction.TransactionAspect; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.core.annotation.Order; @Configuration @EnableAspectJAutoProxy @@ -36,6 +38,13 @@ public class TransactionAspectConfig { return new CompensationMessageHandler(sender, context); } + @Order(0) + @Bean + SagaStartAspect sagaStartAspect(MessageSender sender, OmegaContext context) { + return new SagaStartAspect(sender, context); + } + + @Order(1) @Bean TransactionAspect transactionAspect(MessageSender sender, OmegaContext context) { return new TransactionAspect(sender, context); diff --git a/omega/omega-spring-tx/src/test/java/org/apache/servicecomb/saga/omega/transaction/spring/TransactionInterceptionTest.java b/omega/omega-spring-tx/src/test/java/org/apache/servicecomb/saga/omega/transaction/spring/TransactionInterceptionTest.java index 3dc8c73..c30953f 100644 --- a/omega/omega-spring-tx/src/test/java/org/apache/servicecomb/saga/omega/transaction/spring/TransactionInterceptionTest.java +++ b/omega/omega-spring-tx/src/test/java/org/apache/servicecomb/saga/omega/transaction/spring/TransactionInterceptionTest.java @@ -28,6 +28,7 @@ import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.List; @@ -35,8 +36,9 @@ import java.util.UUID; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +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.UniqueIdGenerator; import org.apache.servicecomb.saga.omega.transaction.MessageHandler; import org.apache.servicecomb.saga.omega.transaction.MessageSender; import org.apache.servicecomb.saga.omega.transaction.TxAbortedEvent; @@ -50,6 +52,7 @@ import org.junit.AfterClass; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; @@ -68,9 +71,11 @@ import akka.actor.Props; @SpringBootTest(classes = {TransactionTestMain.class, MessageConfig.class}) @AutoConfigureMockMvc public class TransactionInterceptionTest { + @SuppressWarnings("unchecked") + private static final IdGenerator<String> idGenerator = Mockito.mock(IdGenerator.class); private static final String globalTxId = UUID.randomUUID().toString(); - private final String localTxId = UUID.randomUUID().toString(); - private final String parentTxId = UUID.randomUUID().toString(); + private final String newLocalTxId = UUID.randomUUID().toString(); + private final String anotherLocalTxId = UUID.randomUUID().toString(); private final String username = uniquify("username"); private final String email = uniquify("email"); @@ -102,9 +107,9 @@ public class TransactionInterceptionTest { @Before public void setUp() throws Exception { + when(idGenerator.nextId()).thenReturn(newLocalTxId, anotherLocalTxId); omegaContext.setGlobalTxId(globalTxId); - omegaContext.setLocalTxId(localTxId); - omegaContext.setParentTxId(parentTxId); + omegaContext.setLocalTxId(globalTxId); compensationMethod = TransactionalUserService.class.getDeclaredMethod("delete", User.class).toString(); } @@ -125,8 +130,8 @@ public class TransactionInterceptionTest { assertArrayEquals( new String[]{ - new TxStartedEvent(globalTxId, localTxId, parentTxId, compensationMethod, user).toString(), - new TxEndedEvent(globalTxId, localTxId, parentTxId, compensationMethod).toString()}, + new TxStartedEvent(globalTxId, newLocalTxId, globalTxId, compensationMethod, user).toString(), + new TxEndedEvent(globalTxId, newLocalTxId, globalTxId, compensationMethod).toString()}, toArray(messages) ); @@ -146,8 +151,8 @@ public class TransactionInterceptionTest { assertArrayEquals( new String[]{ - new TxStartedEvent(globalTxId, localTxId, parentTxId, compensationMethod, illegalUser).toString(), - new TxAbortedEvent(globalTxId, localTxId, parentTxId, compensationMethod, throwable).toString()}, + new TxStartedEvent(globalTxId, newLocalTxId, globalTxId, compensationMethod, illegalUser).toString(), + new TxAbortedEvent(globalTxId, newLocalTxId, globalTxId, compensationMethod, throwable).toString()}, toArray(messages) ); } @@ -160,20 +165,20 @@ public class TransactionInterceptionTest { String localTxId = omegaContext.newLocalTxId(); User anotherUser = userService.add(jack); - messageHandler.onReceive(globalTxId, this.localTxId, parentTxId, compensationMethod, user); - messageHandler.onReceive(globalTxId, localTxId, parentTxId, compensationMethod, anotherUser); + messageHandler.onReceive(globalTxId, newLocalTxId, globalTxId, compensationMethod, user); + messageHandler.onReceive(globalTxId, anotherLocalTxId, localTxId, compensationMethod, anotherUser); assertThat(userRepository.findOne(user.id()), is(nullValue())); assertThat(userRepository.findOne(anotherUser.id()), is(nullValue())); assertArrayEquals( new String[]{ - new TxStartedEvent(globalTxId, this.localTxId, parentTxId, compensationMethod, user).toString(), - new TxEndedEvent(globalTxId, this.localTxId, parentTxId, compensationMethod).toString(), - new TxStartedEvent(globalTxId, localTxId, parentTxId, compensationMethod, anotherUser).toString(), - new TxEndedEvent(globalTxId, localTxId, parentTxId, compensationMethod).toString(), - new TxCompensatedEvent(globalTxId, this.localTxId, parentTxId, compensationMethod).toString(), - new TxCompensatedEvent(globalTxId, localTxId, parentTxId, compensationMethod).toString() + new TxStartedEvent(globalTxId, newLocalTxId, globalTxId, compensationMethod, user).toString(), + new TxEndedEvent(globalTxId, newLocalTxId, globalTxId, compensationMethod).toString(), + new TxStartedEvent(globalTxId, anotherLocalTxId, localTxId, compensationMethod, anotherUser).toString(), + new TxEndedEvent(globalTxId, anotherLocalTxId, localTxId, compensationMethod).toString(), + new TxCompensatedEvent(globalTxId, newLocalTxId, globalTxId, compensationMethod).toString(), + new TxCompensatedEvent(globalTxId, anotherLocalTxId, localTxId, compensationMethod).toString() }, toArray(messages) ); @@ -184,16 +189,16 @@ public class TransactionInterceptionTest { new Thread(() -> userService.add(user)).start(); waitTillSavedUser(username); - String newLocalTxId = omegaContext.newLocalTxId(); + String localTxId = omegaContext.newLocalTxId(); new Thread(() -> userService.add(jack)).start(); waitTillSavedUser(usernameJack); assertArrayEquals( new String[]{ - new TxStartedEvent(globalTxId, localTxId, parentTxId, compensationMethod, user).toString(), - new TxEndedEvent(globalTxId, localTxId, parentTxId, compensationMethod).toString(), - new TxStartedEvent(globalTxId, newLocalTxId, parentTxId, compensationMethod, jack).toString(), - new TxEndedEvent(globalTxId, newLocalTxId, parentTxId, compensationMethod).toString()}, + new TxStartedEvent(globalTxId, newLocalTxId, globalTxId, compensationMethod, user).toString(), + new TxEndedEvent(globalTxId, newLocalTxId, globalTxId, compensationMethod).toString(), + new TxStartedEvent(globalTxId, anotherLocalTxId, localTxId, compensationMethod, jack).toString(), + new TxEndedEvent(globalTxId, anotherLocalTxId, localTxId, compensationMethod).toString()}, toArray(messages) ); } @@ -203,16 +208,16 @@ public class TransactionInterceptionTest { executor.schedule(() -> userService.add(user), 0, MILLISECONDS); waitTillSavedUser(username); - String newLocalTxId = omegaContext.newLocalTxId(); + String localTxId = omegaContext.newLocalTxId(); executor.invokeAll(singletonList(() -> userService.add(jack))); waitTillSavedUser(usernameJack); assertArrayEquals( new String[]{ - new TxStartedEvent(globalTxId, localTxId, parentTxId, compensationMethod, user).toString(), - new TxEndedEvent(globalTxId, localTxId, parentTxId, compensationMethod).toString(), - new TxStartedEvent(globalTxId, newLocalTxId, parentTxId, compensationMethod, jack).toString(), - new TxEndedEvent(globalTxId, newLocalTxId, parentTxId, compensationMethod).toString()}, + new TxStartedEvent(globalTxId, newLocalTxId, globalTxId, compensationMethod, user).toString(), + new TxEndedEvent(globalTxId, newLocalTxId, globalTxId, compensationMethod).toString(), + new TxStartedEvent(globalTxId, anotherLocalTxId, localTxId, compensationMethod, jack).toString(), + new TxEndedEvent(globalTxId, anotherLocalTxId, localTxId, compensationMethod).toString()}, toArray(messages) ); } @@ -231,8 +236,8 @@ public class TransactionInterceptionTest { assertArrayEquals( new String[]{ - new TxStartedEvent(globalTxId, localTxId, parentTxId, compensationMethod, user).toString(), - new TxEndedEvent(globalTxId, localTxId, parentTxId, compensationMethod).toString()}, + new TxStartedEvent(globalTxId, newLocalTxId, globalTxId, compensationMethod, user).toString(), + new TxEndedEvent(globalTxId, newLocalTxId, globalTxId, compensationMethod).toString()}, toArray(messages) ); } @@ -249,8 +254,8 @@ public class TransactionInterceptionTest { assertArrayEquals( new String[] { - new TxStartedEvent(globalTxId, localTxId, parentTxId, compensationMethod, user).toString(), - new TxEndedEvent(globalTxId, localTxId, parentTxId, compensationMethod).toString()}, + new TxStartedEvent(globalTxId, newLocalTxId, globalTxId, compensationMethod, user).toString(), + new TxEndedEvent(globalTxId, newLocalTxId, globalTxId, compensationMethod).toString()}, toArray(messages) ); @@ -289,8 +294,13 @@ public class TransactionInterceptionTest { private final List<String> messages = new ArrayList<>(); @Bean + CompensationContext compensationContext() { + return new CompensationContext(); + } + + @Bean OmegaContext omegaContext() { - return new OmegaContext(new UniqueIdGenerator()); + return new OmegaContext(idGenerator); } @Bean diff --git a/omega/omega-transaction/src/main/java/org/apache/servicecomb/saga/omega/transaction/SagaStartAnnotationProcessor.java b/omega/omega-transaction/src/main/java/org/apache/servicecomb/saga/omega/transaction/SagaStartAnnotationProcessor.java index e92ebb1..64f47ce 100644 --- a/omega/omega-transaction/src/main/java/org/apache/servicecomb/saga/omega/transaction/SagaStartAnnotationProcessor.java +++ b/omega/omega-transaction/src/main/java/org/apache/servicecomb/saga/omega/transaction/SagaStartAnnotationProcessor.java @@ -19,10 +19,9 @@ package org.apache.servicecomb.saga.omega.transaction; import org.apache.servicecomb.saga.omega.context.OmegaContext; -public class SagaStartAnnotationProcessor { +class SagaStartAnnotationProcessor { private final OmegaContext omegaContext; - private final MessageSender sender; SagaStartAnnotationProcessor(OmegaContext omegaContext, MessageSender sender) { @@ -31,7 +30,7 @@ public class SagaStartAnnotationProcessor { } void preIntercept() { - String globalTxId = omegaContext.newGlobalTxId(); + String globalTxId = globalTxId(); // reuse the globalTxId as localTxId to differ localTxId in SagaStartedEvent and the first TxStartedEvent sender.send(new SagaStartedEvent(globalTxId, globalTxId)); } @@ -39,5 +38,12 @@ public class SagaStartAnnotationProcessor { void postIntercept() { String globalTxId = omegaContext.globalTxId(); sender.send(new SagaEndedEvent(globalTxId, globalTxId)); + omegaContext.clear(); + } + + private String globalTxId() { + String globalTxId = omegaContext.newGlobalTxId(); + omegaContext.setLocalTxId(globalTxId); + return globalTxId; } } diff --git a/omega/omega-transaction/src/main/java/org/apache/servicecomb/saga/omega/transaction/SagaStartAspect.java b/omega/omega-transaction/src/main/java/org/apache/servicecomb/saga/omega/transaction/SagaStartAspect.java new file mode 100644 index 0000000..307af3c --- /dev/null +++ b/omega/omega-transaction/src/main/java/org/apache/servicecomb/saga/omega/transaction/SagaStartAspect.java @@ -0,0 +1,60 @@ +/* + * 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.transaction; + +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Method; + +import org.apache.servicecomb.saga.omega.context.OmegaContext; +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 +public class SagaStartAspect { + private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + private final SagaStartAnnotationProcessor sagaStartAnnotationProcessor; + private final OmegaContext context; + + public SagaStartAspect(MessageSender sender, OmegaContext context) { + this.context = context; + this.sagaStartAnnotationProcessor = new SagaStartAnnotationProcessor(context, sender); + } + + @Around("execution(@org.apache.servicecomb.saga.omega.context.annotations.SagaStart * *(..))") + Object advise(ProceedingJoinPoint joinPoint) throws Throwable { + Method method = ((MethodSignature) joinPoint.getSignature()).getMethod(); + + sagaStartAnnotationProcessor.preIntercept(); + LOG.debug("Initialized context {} before execution of method {}", context, method.toString()); + + try { + return joinPoint.proceed(); + } catch (Throwable throwable) { + LOG.error("Failed to process SagaStart method: {}", method.toString()); + throw throwable; + } finally { + LOG.debug("Transaction with context {} has finished.", context); + sagaStartAnnotationProcessor.postIntercept(); + } + } +} 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 5a39c0d..f62b92e 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 @@ -36,7 +36,6 @@ public class TransactionAspect { private final PostTransactionInterceptor postTransactionInterceptor; private final FailedTransactionInterceptor failedTransactionInterceptor; - private final SagaStartAnnotationProcessor sagaStartAnnotationProcessor; private final OmegaContext context; public TransactionAspect(MessageSender sender, OmegaContext context) { @@ -44,7 +43,6 @@ public class TransactionAspect { this.preTransactionInterceptor = new PreTransactionInterceptor(sender); this.postTransactionInterceptor = new PostTransactionInterceptor(sender); this.failedTransactionInterceptor = new FailedTransactionInterceptor(sender); - this.sagaStartAnnotationProcessor = new SagaStartAnnotationProcessor(context, sender); } @Around("execution(@org.apache.servicecomb.saga.omega.transaction.annotations.Compensable * *(..)) && @annotation(compensable)") @@ -54,7 +52,12 @@ public class TransactionAspect { String signature = compensationMethodSignature(joinPoint, compensable, method); + String localTxId = context.localTxId(); + String parentTxId = context.parentTxId(); + context.setParentTxId(localTxId); + preIntercept(joinPoint, signature); + LOG.debug("Updated context {} for compensable method {} ", context, method.toString()); try { Object result = joinPoint.proceed(); @@ -64,26 +67,10 @@ public class TransactionAspect { } catch (Throwable throwable) { interceptException(signature, throwable); throw throwable; - } - } - - @Around("execution(@org.apache.servicecomb.saga.omega.context.annotations.SagaStart * *(..))") - Object advise(ProceedingJoinPoint joinPoint) throws Throwable { - Method method = ((MethodSignature) joinPoint.getSignature()).getMethod(); - - LOG.debug("Initializing global tx id before execution of method {}", method.toString()); - sagaStartAnnotationProcessor.preIntercept(); - - try { - Object result = joinPoint.proceed(); - - LOG.info("Transaction {} succeeded.", context.globalTxId()); - sagaStartAnnotationProcessor.postIntercept(); - - return result; - } catch (Throwable throwable) { - LOG.error("Transaction {} failed.", context.globalTxId()); - throw throwable; + } finally { + context.setLocalTxId(localTxId); + context.setParentTxId(parentTxId); + LOG.debug("Restored context back to {}", context); } } @@ -97,12 +84,9 @@ public class TransactionAspect { } private void preIntercept(ProceedingJoinPoint joinPoint, String signature) { - // context without a parent should be the first TxStartedEvent - initFirstOmegaContext(); - preTransactionInterceptor.intercept( context.globalTxId(), - context.localTxId(), + context.newLocalTxId(), context.parentTxId(), signature, joinPoint.getArgs()); @@ -124,14 +108,4 @@ public class TransactionAspect { signature, throwable); } - - private void initFirstOmegaContext() { - if (context.parentTxId() != null) { - return; - } - if (context.localTxId() == null) { - context.newLocalTxId(); - } - context.setParentTxId(context.globalTxId()); - } } diff --git a/omega/omega-transaction/src/test/java/org/apache/servicecomb/saga/omega/transaction/SagaStartAnnotationProcessorTest.java b/omega/omega-transaction/src/test/java/org/apache/servicecomb/saga/omega/transaction/SagaStartAnnotationProcessorTest.java index 8913b7f..fba7826 100644 --- a/omega/omega-transaction/src/test/java/org/apache/servicecomb/saga/omega/transaction/SagaStartAnnotationProcessorTest.java +++ b/omega/omega-transaction/src/test/java/org/apache/servicecomb/saga/omega/transaction/SagaStartAnnotationProcessorTest.java @@ -41,9 +41,9 @@ public class SagaStartAnnotationProcessorTest { private final String localTxId = UUID.randomUUID().toString(); - private final IdGenerator generator = mock(IdGenerator.class); - @SuppressWarnings("unchecked") + private final IdGenerator<String> generator = mock(IdGenerator.class); + private final OmegaContext context = new OmegaContext(generator); private final SagaStartAnnotationProcessor sagaStartAnnotationProcessor = new SagaStartAnnotationProcessor(context, @@ -56,7 +56,7 @@ public class SagaStartAnnotationProcessorTest { sagaStartAnnotationProcessor.preIntercept(); assertThat(context.globalTxId(), is(globalTxId)); - assertThat(context.localTxId(), is(nullValue())); + assertThat(context.localTxId(), is(globalTxId)); assertThat(context.parentTxId(), is(nullValue())); TxEvent event = messages.get(0); @@ -73,7 +73,6 @@ public class SagaStartAnnotationProcessorTest { public void sendsSagaEndedEvent() { context.clear(); context.setGlobalTxId(globalTxId); - context.setLocalTxId(localTxId); sagaStartAnnotationProcessor.postIntercept(); @@ -85,5 +84,9 @@ public class SagaStartAnnotationProcessorTest { assertThat(event.compensationMethod().isEmpty(), is(true)); assertThat(event.type(), is("SagaEndedEvent")); assertThat(event.payloads().length, is(0)); + + assertThat(context.globalTxId(), is(nullValue())); + assertThat(context.localTxId(), is(nullValue())); + assertThat(context.parentTxId(), is(nullValue())); } } \ No newline at end of file diff --git a/omega/omega-transaction/src/test/java/org/apache/servicecomb/saga/omega/transaction/SagaStartAspectTest.java b/omega/omega-transaction/src/test/java/org/apache/servicecomb/saga/omega/transaction/SagaStartAspectTest.java new file mode 100644 index 0000000..cfaa7b6 --- /dev/null +++ b/omega/omega-transaction/src/test/java/org/apache/servicecomb/saga/omega/transaction/SagaStartAspectTest.java @@ -0,0 +1,124 @@ +/* + * 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.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.when; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.apache.servicecomb.saga.omega.context.IdGenerator; +import org.apache.servicecomb.saga.omega.context.OmegaContext; +import org.apache.servicecomb.saga.omega.transaction.annotations.Compensable; +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 SagaStartAspectTest { + private final List<TxEvent> messages = new ArrayList<>(); + private final String globalTxId = UUID.randomUUID().toString(); + private final String localTxId = UUID.randomUUID().toString(); + private final String parentTxId = UUID.randomUUID().toString(); + + private final MessageSender sender = messages::add; + 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 Compensable compensable = Mockito.mock(Compensable.class); + + private final OmegaContext omegaContext = new OmegaContext(idGenerator); + private final SagaStartAspect aspect = new SagaStartAspect(sender, omegaContext); + + @Before + public void setUp() throws Exception { + when(joinPoint.getSignature()).thenReturn(methodSignature); + when(joinPoint.getTarget()).thenReturn(this); + + when(methodSignature.getMethod()).thenReturn(this.getClass().getDeclaredMethod("doNothing")); + when(compensable.compensationMethod()).thenReturn("doNothing"); + + omegaContext.setGlobalTxId(globalTxId); + omegaContext.setLocalTxId(localTxId); + omegaContext.setParentTxId(parentTxId); + } + + @Test + public void newGlobalTxIdInSagaStart() throws Throwable { + omegaContext.clear(); + when(idGenerator.nextId()).thenReturn(globalTxId); + + aspect.advise(joinPoint); + + TxEvent startedEvent = messages.get(0); + + assertThat(startedEvent.globalTxId(), is(globalTxId)); + assertThat(startedEvent.localTxId(), is(globalTxId)); + assertThat(startedEvent.parentTxId(), is(nullValue())); + assertThat(startedEvent.type(), is("SagaStartedEvent")); + + TxEvent endedEvent = messages.get(1); + + assertThat(endedEvent.globalTxId(), is(globalTxId)); + assertThat(endedEvent.localTxId(), is(globalTxId)); + assertThat(endedEvent.parentTxId(), is(nullValue())); + assertThat(endedEvent.type(), is("SagaEndedEvent")); + + assertThat(omegaContext.globalTxId(), is(nullValue())); + assertThat(omegaContext.localTxId(), is(nullValue())); + assertThat(omegaContext.parentTxId(), is(nullValue())); + } + + @Test + public void clearContextOnSagaStartError() throws Throwable { + when(idGenerator.nextId()).thenReturn(globalTxId); + RuntimeException oops = new RuntimeException("oops"); + + when(joinPoint.proceed()).thenThrow(oops); + + try { + aspect.advise(joinPoint); + expectFailing(RuntimeException.class); + } catch (RuntimeException e) { + assertThat(e, is(oops)); + } + + TxEvent event = messages.get(1); + + assertThat(event.globalTxId(), is(globalTxId)); + assertThat(event.localTxId(), is(globalTxId)); + assertThat(event.parentTxId(), is(nullValue())); + assertThat(event.type(), is("SagaEndedEvent")); + + assertThat(omegaContext.globalTxId(), is(nullValue())); + assertThat(omegaContext.localTxId(), is(nullValue())); + assertThat(omegaContext.parentTxId(), is(nullValue())); + } + + private String doNothing() { + return "doNothing"; + } +} diff --git a/omega/omega-transaction/src/test/java/org/apache/servicecomb/saga/omega/transaction/TransactionAspectTest.java b/omega/omega-transaction/src/test/java/org/apache/servicecomb/saga/omega/transaction/TransactionAspectTest.java new file mode 100644 index 0000000..bd8829c --- /dev/null +++ b/omega/omega-transaction/src/test/java/org/apache/servicecomb/saga/omega/transaction/TransactionAspectTest.java @@ -0,0 +1,124 @@ +/* + * 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.transaction; + +import static com.seanyinx.github.unit.scaffolding.AssertUtils.expectFailing; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.apache.servicecomb.saga.omega.context.IdGenerator; +import org.apache.servicecomb.saga.omega.context.OmegaContext; +import org.apache.servicecomb.saga.omega.transaction.annotations.Compensable; +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 TransactionAspectTest { + private final List<TxEvent> messages = new ArrayList<>(); + private final String globalTxId = UUID.randomUUID().toString(); + private final String localTxId = UUID.randomUUID().toString(); + private final String parentTxId = UUID.randomUUID().toString(); + + private final String newLocalTxId = UUID.randomUUID().toString(); + + private final MessageSender sender = messages::add; + 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 Compensable compensable = Mockito.mock(Compensable.class); + + private final OmegaContext omegaContext = new OmegaContext(idGenerator); + private final TransactionAspect aspect = new TransactionAspect(sender, omegaContext); + + @Before + public void setUp() throws Exception { + when(joinPoint.getSignature()).thenReturn(methodSignature); + when(joinPoint.getTarget()).thenReturn(this); + + when(methodSignature.getMethod()).thenReturn(this.getClass().getDeclaredMethod("doNothing")); + when(compensable.compensationMethod()).thenReturn("doNothing"); + + omegaContext.setGlobalTxId(globalTxId); + omegaContext.setLocalTxId(localTxId); + omegaContext.setParentTxId(parentTxId); + } + + @Test + public void newLocalTxIdInCompensable() throws Throwable { + when(idGenerator.nextId()).thenReturn(newLocalTxId); + + aspect.advise(joinPoint, compensable); + + TxEvent startedEvent = messages.get(0); + + assertThat(startedEvent.globalTxId(), is(globalTxId)); + assertThat(startedEvent.localTxId(), is(newLocalTxId)); + assertThat(startedEvent.parentTxId(), is(localTxId)); + assertThat(startedEvent.type(), is("TxStartedEvent")); + + TxEvent endedEvent = messages.get(1); + + assertThat(endedEvent.globalTxId(), is(globalTxId)); + assertThat(endedEvent.localTxId(), is(newLocalTxId)); + assertThat(endedEvent.parentTxId(), is(localTxId)); + assertThat(endedEvent.type(), is("TxEndedEvent")); + + assertThat(omegaContext.globalTxId(), is(globalTxId)); + assertThat(omegaContext.localTxId(), is(localTxId)); + assertThat(omegaContext.parentTxId(), is(parentTxId)); + } + + @Test + public void restoreContextOnCompensableError() throws Throwable { + when(idGenerator.nextId()).thenReturn(newLocalTxId); + RuntimeException oops = new RuntimeException("oops"); + + when(joinPoint.proceed()).thenThrow(oops); + + try { + aspect.advise(joinPoint, compensable); + expectFailing(RuntimeException.class); + } catch (RuntimeException e) { + assertThat(e, is(oops)); + } + + TxEvent event = messages.get(1); + + assertThat(event.globalTxId(), is(globalTxId)); + assertThat(event.localTxId(), is(newLocalTxId)); + assertThat(event.parentTxId(), is(localTxId)); + assertThat(event.type(), is("TxAbortedEvent")); + + assertThat(omegaContext.globalTxId(), is(globalTxId)); + assertThat(omegaContext.localTxId(), is(localTxId)); + assertThat(omegaContext.parentTxId(), is(parentTxId)); + } + + private String doNothing() { + return "doNothing"; + } +} diff --git a/omega/omega-transport/omega-transport-resttemplate/src/main/java/org/apache/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptor.java b/omega/omega-transport/omega-transport-resttemplate/src/main/java/org/apache/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptor.java index 3e5d620..9b003f8 100644 --- a/omega/omega-transport/omega-transport-resttemplate/src/main/java/org/apache/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptor.java +++ b/omega/omega-transport/omega-transport-resttemplate/src/main/java/org/apache/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptor.java @@ -20,6 +20,9 @@ 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.lang.invoke.MethodHandles; import javax.servlet.http.HttpServletRequest; @@ -43,24 +46,21 @@ class TransactionHandlerInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { - String globalTxId = request.getHeader(OmegaContext.GLOBAL_TX_ID_KEY); + String globalTxId = request.getHeader(GLOBAL_TX_ID_KEY); if (globalTxId == null) { - LOG.debug("no such header: {}", OmegaContext.GLOBAL_TX_ID_KEY); + LOG.debug("no such header: {}", GLOBAL_TX_ID_KEY); } else { omegaContext.setGlobalTxId(globalTxId); - omegaContext.newLocalTxId(); - omegaContext.setParentTxId(request.getHeader(OmegaContext.LOCAL_TX_ID_KEY)); + omegaContext.setLocalTxId(request.getHeader(LOCAL_TX_ID_KEY)); } return true; } @Override - public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, - ModelAndView modelAndView) { + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView mv) { } @Override - public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, - Exception e) { + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) { } } diff --git a/omega/omega-transport/omega-transport-resttemplate/src/test/java/org/apache/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptorTest.java b/omega/omega-transport/omega-transport-resttemplate/src/test/java/org/apache/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptorTest.java index 6ee816b..03f278f 100644 --- a/omega/omega-transport/omega-transport-resttemplate/src/test/java/org/apache/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptorTest.java +++ b/omega/omega-transport/omega-transport-resttemplate/src/test/java/org/apache/servicecomb/saga/omega/transport/resttemplate/TransactionHandlerInterceptorTest.java @@ -51,9 +51,7 @@ public class TransactionHandlerInterceptorTest { @Before public void setUp() { - omegaContext.setGlobalTxId(null); - omegaContext.setLocalTxId(null); - omegaContext.setParentTxId(null); + omegaContext.clear(); } @Test @@ -64,8 +62,8 @@ public class TransactionHandlerInterceptorTest { requestInterceptor.preHandle(request, response, null); assertThat(omegaContext.globalTxId(), is(globalTxId)); - assertThat(omegaContext.localTxId(), is(notNullValue())); - assertThat(omegaContext.parentTxId(), is(localTxId)); + assertThat(omegaContext.localTxId(), is(localTxId)); + assertThat(omegaContext.parentTxId(), is(nullValue())); } @Test -- To stop receiving notification emails like this one, please contact "commits@servicecomb.apache.org" <commits@servicecomb.apache.org>.