Skip to content

Commit

Permalink
SCB-817 Added the unit tests of TCC related Aspect
Browse files Browse the repository at this point in the history
  • Loading branch information
WillemJiang committed Aug 23, 2018
1 parent e8b46be commit 6dee598
Show file tree
Hide file tree
Showing 10 changed files with 534 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,5 @@ public interface TccEventService {
AlphaResponse TccTransactionStart(TccStartedEvent tccStartEvent);

AlphaResponse TccTransactionStop(TccEndedEvent tccEndEvent);

AlphaResponse send(TxEvent event);

}
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,14 @@ Object advise(ProceedingJoinPoint joinPoint, Participate participate) throws Thr
try {
Object result = joinPoint.proceed();
// Send the participate message back
tccEventService.participate(new ParticipatedEvent(context.globalTxId(), context.localTxId(), localTxId, cancelMethod, confirmMethod,
TransactionStatus.Succeed));
tccEventService.participate(new ParticipatedEvent(context.globalTxId(), context.localTxId(), localTxId, confirmMethod,
cancelMethod, TransactionStatus.Succeed));
LOG.debug("Participate Transaction with context {} has finished.", context);
return result;
} catch (Throwable throwable) {
// Now we don't handle the error message
tccEventService.participate(new ParticipatedEvent(context.globalTxId(), context.localTxId(), localTxId, cancelMethod,
confirmMethod, TransactionStatus.Failed));
tccEventService.participate(new ParticipatedEvent(context.globalTxId(), context.localTxId(), localTxId, confirmMethod,
cancelMethod, TransactionStatus.Failed));
LOG.error("Participate Transaction with context {} failed.", context, throwable);
throw throwable;
} finally {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,11 @@
import org.apache.servicecomb.saga.common.TransactionStatus;
import org.apache.servicecomb.saga.omega.context.OmegaContext;
import org.apache.servicecomb.saga.omega.transaction.AlphaResponse;
import org.apache.servicecomb.saga.omega.transaction.EventAwareInterceptor;
import org.apache.servicecomb.saga.omega.transaction.OmegaException;
import org.apache.servicecomb.saga.omega.transaction.TxAbortedEvent;
import org.apache.servicecomb.saga.omega.transaction.tcc.events.TccEndedEvent;
import org.apache.servicecomb.saga.omega.transaction.tcc.events.TccStartedEvent;

public class TccStartAnnotationProcessor implements EventAwareInterceptor {
public class TccStartAnnotationProcessor {

private final OmegaContext omegaContext;
private final TccEventService eventService;
Expand All @@ -37,24 +35,20 @@ public class TccStartAnnotationProcessor implements EventAwareInterceptor {
this.eventService = eventService;
}

@Override
public AlphaResponse preIntercept(String parentTxId, String compensationMethod, int timeout, String retriesMethod,
int retries, Object... message) {
public AlphaResponse preIntercept(String parentTxId, String methodName, int timeout) {
try {
return eventService.TccTransactionStart(new TccStartedEvent(omegaContext.globalTxId(), omegaContext.localTxId()));
} catch (OmegaException e) {
throw new TransactionalException(e.getMessage(), e.getCause());
}
}

@Override
public void postIntercept(String parentTxId, String compensationMethod) {
public void postIntercept(String parentTxId, String methodName) {
eventService.TccTransactionStop(new TccEndedEvent(omegaContext.globalTxId(), omegaContext.localTxId(),
TransactionStatus.Succeed));
}

@Override
public void onError(String parentTxId, String compensationMethod, Throwable throwable) {
public void onError(String parentTxId, String methodName, Throwable throwable) {
// Send the cancel event
// Do we need to wait for the alpha finish all the transaction
eventService.TccTransactionStop(new TccEndedEvent(omegaContext.globalTxId(), omegaContext.localTxId(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@
import java.lang.reflect.Method;

import org.apache.servicecomb.saga.omega.context.OmegaContext;
import org.apache.servicecomb.saga.omega.context.annotations.SagaStart;
import org.apache.servicecomb.saga.omega.context.annotations.TccStart;
import org.apache.servicecomb.saga.omega.transaction.MessageSender;
import org.apache.servicecomb.saga.omega.transaction.OmegaException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
Expand All @@ -49,7 +47,7 @@ Object advise(ProceedingJoinPoint joinPoint, TccStart tccStart) throws Throwable
initializeOmegaContext();
Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();

tccStartAnnotationProcessor.preIntercept(context.globalTxId(), method.toString(), tccStart.timeout(), "", 0);
tccStartAnnotationProcessor.preIntercept(context.globalTxId(), method.toString(), tccStart.timeout());
LOG.debug("Initialized context {} before execution of method {}", context, method.toString());

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,28 @@ public ParticipatedEvent(String globalTxId, String localTxId, String parentTxId,
this.cancelMethod = cancelMethod;
this.status = status;
}

public String getGlobalTxId() {
return globalTxId;
}

public String getLocalTxId() {
return localTxId;
}

public String getParentTxId() {
return parentTxId;
}

public String getConfirmMethod() {
return confirmMethod;
}

public String getCancelMethod() {
return cancelMethod;
}

public TransactionStatus getStatus() {
return status;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,19 @@ public class TccEndedEvent {
private final String globalTxId;
private final String localTxId;
private final TransactionStatus status;



public String getGlobalTxId() {
return globalTxId;
}

public String getLocalTxId() {
return localTxId;
}

public TransactionStatus getStatus() {
return status;
}

public TccEndedEvent(String globalTxId, String localTxId,
TransactionStatus status) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,13 @@ public class TccStartedEvent {
private final String globalTxId;
private final String localTxId;


public String getGlobalTxId() {
return globalTxId;
}

public String getLocalTxId() {
return localTxId;
}



public TccStartedEvent(String globalTxId, String localTxId) {
this.globalTxId = globalTxId;
this.localTxId = localTxId;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/*
* 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.tcc;

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.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.apache.servicecomb.saga.common.TransactionStatus;
import org.apache.servicecomb.saga.omega.context.IdGenerator;
import org.apache.servicecomb.saga.omega.context.OmegaContext;
import org.apache.servicecomb.saga.omega.context.annotations.TccStart;
import org.apache.servicecomb.saga.omega.transaction.AlphaResponse;
import org.apache.servicecomb.saga.omega.transaction.annotations.Compensable;
import org.apache.servicecomb.saga.omega.transaction.annotations.Participate;
import org.apache.servicecomb.saga.omega.transaction.tcc.events.ParticipatedEvent;
import org.apache.servicecomb.saga.omega.transaction.tcc.events.TccEndedEvent;
import org.apache.servicecomb.saga.omega.transaction.tcc.events.TccStartedEvent;
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 TccParticipatorAspectTest {
private final ProceedingJoinPoint joinPoint = Mockito.mock(ProceedingJoinPoint.class);
private final MethodSignature methodSignature = Mockito.mock(MethodSignature.class);
private final String globalTxId = UUID.randomUUID().toString();
private final String localTxId = UUID.randomUUID().toString();
private final String newLocalTxId = UUID.randomUUID().toString();

private final List<ParticipatedEvent> participatedEvents = new ArrayList<>();
private final AlphaResponse response = new AlphaResponse(false);
private final TccEventService eventService = new TccEventService() {
@Override
public void onConnected() {

}

@Override
public void onDisconnected() {

}

@Override
public void close() {

}

@Override
public String target() {
return null;
}

@Override
public AlphaResponse participate(ParticipatedEvent participateEvent) {
participatedEvents.add(participateEvent);
return response;
}

@Override
public AlphaResponse TccTransactionStart(TccStartedEvent tccStartEvent) {
return null;
}

@Override
public AlphaResponse TccTransactionStop(TccEndedEvent tccEndEvent) {
return null;
}

};


@SuppressWarnings("unchecked")
private final IdGenerator<String> idGenerator = Mockito.mock(IdGenerator.class);

private final OmegaContext omegaContext = new OmegaContext(idGenerator);
private final Participate participate = mock(Participate.class);

private final TccParticipatorAspect aspect = new TccParticipatorAspect(eventService, omegaContext);


@Before
public void setUp() throws Exception {
when(idGenerator.nextId()).thenReturn(newLocalTxId);
when(joinPoint.getSignature()).thenReturn(methodSignature);
when(joinPoint.getTarget()).thenReturn(this);

when(methodSignature.getMethod()).thenReturn(this.getClass().getDeclaredMethod("doNothing"));
when(participate.cancelMethod()).thenReturn("cancelMethod");
when(participate.confirmMethod()).thenReturn("confirmMethod");

omegaContext.setGlobalTxId(globalTxId);
omegaContext.setLocalTxId(localTxId);
}

@Test
public void participateMethodIsCalledSuccessed() throws Throwable {
aspect.advise(joinPoint, participate);

assertThat(participatedEvents.size(), is(1));
ParticipatedEvent participatedEvent = participatedEvents.get(0);

assertThat(participatedEvent.getGlobalTxId(), is(globalTxId));
assertThat(participatedEvent.getParentTxId(), is(localTxId));
assertThat(participatedEvent.getLocalTxId(), is(newLocalTxId));
assertThat(participatedEvent.getStatus(), is(TransactionStatus.Succeed));
assertThat(participatedEvent.getCancelMethod(), is("cancelMethod"));
assertThat(participatedEvent.getConfirmMethod(), is("confirmMethod"));

assertThat(omegaContext.globalTxId(), is(globalTxId));
assertThat(omegaContext.localTxId(), is(localTxId));
}

@Test
public void participateMethodIsCalledFailed() throws Throwable {
RuntimeException oops = new RuntimeException("oops");

when(joinPoint.proceed()).thenThrow(oops);

try {
aspect.advise(joinPoint, participate);
expectFailing(RuntimeException.class);
} catch (RuntimeException e) {
assertThat(e, is(oops));
}

assertThat(participatedEvents.size(), is(1));
ParticipatedEvent participatedEvent = participatedEvents.get(0);

assertThat(participatedEvent.getGlobalTxId(), is(globalTxId));
assertThat(participatedEvent.getParentTxId(), is(localTxId));
assertThat(participatedEvent.getLocalTxId(), is(newLocalTxId));
assertThat(participatedEvent.getStatus(), is(TransactionStatus.Failed));
assertThat(participatedEvent.getCancelMethod(), is("cancelMethod"));
assertThat(participatedEvent.getConfirmMethod(), is("confirmMethod"));


assertThat(omegaContext.globalTxId(), is(globalTxId));
assertThat(omegaContext.localTxId(), is(localTxId));
}

private String doNothing() {
return "doNothing";
}

}

0 comments on commit 6dee598

Please sign in to comment.