motan框架支持

This commit is contained in:
yu199195 2017-12-19 18:25:03 +08:00
parent 314374a1ea
commit e9ba267567
9 changed files with 410 additions and 2 deletions

View File

@ -45,7 +45,13 @@ public enum TccRoleEnum {
/**
* Provider tcc role enum.
*/
PROVIDER(3, "提供者");
PROVIDER(3, "提供者"),
/**
* Local tcc role enum.
*/
LOCAL(4,"本地调用");
private int code;

View File

@ -22,6 +22,7 @@ import com.alibaba.dubbo.rpc.RpcContext;
import com.happylifeplat.tcc.common.constant.CommonConstant;
import com.happylifeplat.tcc.common.utils.GsonUtils;
import com.happylifeplat.tcc.common.bean.context.TccTransactionContext;
import com.happylifeplat.tcc.core.concurrent.threadlocal.TransactionContextLocal;
import com.happylifeplat.tcc.core.interceptor.TccTransactionInterceptor;
import com.happylifeplat.tcc.core.service.TccTransactionAspectService;
import org.apache.commons.lang3.StringUtils;
@ -46,10 +47,12 @@ public class DubboTccTransactionInterceptor implements TccTransactionInterceptor
@Override
public Object interceptor(ProceedingJoinPoint pjp) throws Throwable {
final String context = RpcContext.getContext().getAttachment(CommonConstant.TCC_TRANSACTION_CONTEXT);
TccTransactionContext tccTransactionContext = null;
TccTransactionContext tccTransactionContext;
if (StringUtils.isNoneBlank(context)) {
tccTransactionContext =
GsonUtils.getInstance().fromJson(context, TccTransactionContext.class);
} else {
tccTransactionContext = TransactionContextLocal.getInstance().get();
}
return tccTransactionAspectService.invoke(tccTransactionContext, pjp);
}

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>happylifeplat-tcc</artifactId>
<groupId>com.happylifeplat.tcc</groupId>
<version>1.1.0-RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>happylifeplat-tcc-motan</artifactId>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>com.weibo</groupId>
<artifactId>motan-core</artifactId>
</dependency>
<dependency>
<groupId>com.weibo</groupId>
<artifactId>motan-springsupport</artifactId>
</dependency>
<dependency>
<groupId>com.weibo</groupId>
<artifactId>motan-transport-netty</artifactId>
</dependency>
<dependency>
<groupId>com.happylifeplat.tcc</groupId>
<artifactId>happylifeplat-tcc-core</artifactId>
</dependency>
</dependencies>
<build>
<finalName>happylifeplat-tcc-motan</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,149 @@
package com.happylifeplat.tcc.motan.filter;
import com.happylifeplat.tcc.annotation.Tcc;
import com.happylifeplat.tcc.annotation.TccPatternEnum;
import com.happylifeplat.tcc.common.bean.context.TccTransactionContext;
import com.happylifeplat.tcc.common.bean.entity.Participant;
import com.happylifeplat.tcc.common.bean.entity.TccInvocation;
import com.happylifeplat.tcc.common.constant.CommonConstant;
import com.happylifeplat.tcc.common.enums.TccActionEnum;
import com.happylifeplat.tcc.common.exception.TccRuntimeException;
import com.happylifeplat.tcc.common.utils.GsonUtils;
import com.happylifeplat.tcc.core.concurrent.threadlocal.TransactionContextLocal;
import com.happylifeplat.tcc.core.helper.SpringBeanUtils;
import com.happylifeplat.tcc.core.service.handler.TccTransactionManager;
import com.weibo.api.motan.common.MotanConstants;
import com.weibo.api.motan.core.extension.Activation;
import com.weibo.api.motan.core.extension.SpiMeta;
import com.weibo.api.motan.filter.Filter;
import com.weibo.api.motan.rpc.Caller;
import com.weibo.api.motan.rpc.Request;
import com.weibo.api.motan.rpc.Response;
import com.weibo.api.motan.util.ReflectUtil;
import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Method;
import java.util.Objects;
import java.util.stream.Stream;
/**
* @author xiaoyu
*/
@SpiMeta(name = "motanTccTransactionFilter")
@Activation(key = {MotanConstants.NODE_TYPE_REFERER})
public class MotanTccTransactionFilter implements Filter {
/**
* 实现新浪的filter接口 rpc传参数
*
* @param caller caller
* @param request 请求
* @return Response
*/
@Override
@SuppressWarnings("unchecked")
public Response filter(Caller<?> caller, Request request) {
final String interfaceName = request.getInterfaceName();
final String methodName = request.getMethodName();
final Object[] arguments = request.getArguments();
Class[] args = null;
Method method = null;
Tcc tcc = null;
Class clazz = null;
try {
//他妈的 这里还要拿方法参数类型
clazz = ReflectUtil.forName(interfaceName);
final Method[] methods = clazz.getMethods();
args =
Stream.of(methods)
.filter(m -> m.getName().equals(methodName))
.findFirst()
.map(Method::getParameterTypes).get();
method = clazz.getDeclaredMethod(methodName, args);
tcc = method.getAnnotation(Tcc.class);
} catch (Exception e) {
e.printStackTrace();
}
if (Objects.nonNull(tcc)) {
try {
final TccTransactionContext tccTransactionContext =
TransactionContextLocal.getInstance().get();
if (Objects.nonNull(tccTransactionContext)) {
request
.setAttachment(CommonConstant.TCC_TRANSACTION_CONTEXT,
GsonUtils.getInstance().toJson(tccTransactionContext));
}
final Response response = caller.call(request);
final Participant participant = buildParticipant(tccTransactionContext,tcc, method, clazz, arguments, args);
if (Objects.nonNull(participant)) {
SpringBeanUtils.getInstance().getBean(TccTransactionManager.class).enlistParticipant(participant);
}
return response;
} catch (Exception e) {
e.printStackTrace();
throw e;
}
} else {
return caller.call(request);
}
}
@SuppressWarnings("unchecked")
private Participant buildParticipant(TccTransactionContext tccTransactionContext, Tcc tcc,
Method method, Class clazz,
Object[] arguments,
Class... args) throws TccRuntimeException {
if (Objects.nonNull(tccTransactionContext)) {
if (TccActionEnum.TRYING.getCode() == tccTransactionContext.getAction()) {
//获取协调方法
String confirmMethodName = tcc.confirmMethod();
if (StringUtils.isBlank(confirmMethodName)) {
confirmMethodName = method.getName();
}
String cancelMethodName = tcc.cancelMethod();
if (StringUtils.isBlank(cancelMethodName)) {
cancelMethodName = method.getName();
}
//设置模式
final TccPatternEnum pattern = tcc.pattern();
SpringBeanUtils.getInstance().getBean(TccTransactionManager.class)
.getCurrentTransaction().setPattern(pattern.getCode());
TccInvocation confirmInvocation = new TccInvocation(clazz,
confirmMethodName,
args, arguments);
TccInvocation cancelInvocation = new TccInvocation(clazz,
cancelMethodName,
args, arguments);
//封装调用点
return new Participant(
tccTransactionContext.getTransId(),
confirmInvocation,
cancelInvocation);
}
}
return null;
}
}

View File

@ -0,0 +1,46 @@
/*
*
* Copyright 2017-2018 549477611@qq.com(xiaoyu)
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, see <http://www.gnu.org/licenses/>.
*
*/
package com.happylifeplat.tcc.motan.interceptor;
import com.happylifeplat.tcc.core.interceptor.AbstractTccTransactionAspect;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
/**
* @author xiaoyu
*/
@Aspect
@Component
public class MotanTccTransactionAspect extends AbstractTccTransactionAspect implements Ordered {
@Autowired
public MotanTccTransactionAspect(MotanTccTransactionInterceptor motanTccTransactionInterceptor) {
super.setTccTransactionInterceptor(motanTccTransactionInterceptor);
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}

View File

@ -0,0 +1,68 @@
/*
*
* Copyright 2017-2018 549477611@qq.com(xiaoyu)
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, see <http://www.gnu.org/licenses/>.
*
*/
package com.happylifeplat.tcc.motan.interceptor;
import com.happylifeplat.tcc.common.bean.context.TccTransactionContext;
import com.happylifeplat.tcc.common.constant.CommonConstant;
import com.happylifeplat.tcc.common.utils.GsonUtils;
import com.happylifeplat.tcc.core.concurrent.threadlocal.TransactionContextLocal;
import com.happylifeplat.tcc.core.interceptor.TccTransactionInterceptor;
import com.happylifeplat.tcc.core.service.TccTransactionAspectService;
import com.weibo.api.motan.rpc.Request;
import com.weibo.api.motan.rpc.RpcContext;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.Objects;
/**
* @author xiaoyu
*/
@Component
public class MotanTccTransactionInterceptor implements TccTransactionInterceptor {
private final TccTransactionAspectService tccTransactionAspectService;
@Autowired
public MotanTccTransactionInterceptor(TccTransactionAspectService tccTransactionAspectService) {
this.tccTransactionAspectService = tccTransactionAspectService;
}
@Override
public Object interceptor(ProceedingJoinPoint pjp) throws Throwable {
TccTransactionContext tccTransactionContext = null;
final Request request = RpcContext.getContext().getRequest();
if (Objects.nonNull(request)) {
final Map<String, String> attachments = request.getAttachments();
if (attachments != null && !attachments.isEmpty()) {
String context = attachments.get(CommonConstant.TCC_TRANSACTION_CONTEXT);
tccTransactionContext =
GsonUtils.getInstance().fromJson(context, TccTransactionContext.class);
}
} else {
tccTransactionContext = TransactionContextLocal.getInstance().get();
}
return tccTransactionAspectService.invoke(tccTransactionContext, pjp);
}
}

View File

@ -0,0 +1,50 @@
/*
*
* Copyright 2017-2018 549477611@qq.com(xiaoyu)
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, see <http://www.gnu.org/licenses/>.
*
*/
package com.happylifeplat.tcc.motan.service;
import com.happylifeplat.tcc.core.service.ApplicationService;
import com.weibo.api.motan.config.springsupport.BasicServiceConfigBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author xiaoyu
*/
@Service
public class MotanApplicationServiceImpl implements ApplicationService {
private final BasicServiceConfigBean basicServiceConfigBean;
@Autowired
public MotanApplicationServiceImpl(BasicServiceConfigBean basicServiceConfigBean) {
this.basicServiceConfigBean = basicServiceConfigBean;
}
/**
* 获取applicationName
*
* @return applicationName
*/
@Override
public String acquireName() {
return basicServiceConfigBean.getModule();
}
}

View File

@ -0,0 +1 @@
com.happylifeplat.tcc.motan.filter.MotanTccTransactionFilter

28
pom.xml
View File

@ -17,6 +17,7 @@
<module>happylifeplat-tcc-springcloud</module>
<module>happylifeplat-tcc-annotation</module>
<module>happylifeplat-tcc-admin</module>
<module>happylifeplat-tcc-motan</module>
</modules>
<licenses>
@ -71,6 +72,7 @@
<druid.version>1.0.29</druid.version>
<springfox.version>2.6.1</springfox.version>
<lombok.version>1.16.14</lombok.version>
<motan.version>1.0.0</motan.version>
</properties>
@ -164,6 +166,32 @@
</exclusions>
</dependency>
<!-- motan config start-->
<dependency>
<groupId>com.weibo</groupId>
<artifactId>motan-core</artifactId>
<version>${motan.version}</version>
</dependency>
<dependency>
<groupId>com.weibo</groupId>
<artifactId>motan-transport-netty</artifactId>
<version>${motan.version}</version>
</dependency>
<!-- only needed for spring-based features -->
<dependency>
<groupId>com.weibo</groupId>
<artifactId>motan-springsupport</artifactId>
<version>${motan.version}</version>
</dependency>
<dependency>
<groupId>com.weibo</groupId>
<artifactId>motan-registry-zookeeper</artifactId>
<version>${motan.version}</version>
</dependency>
<!-- motan config end-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>