chore(project): 添加项目配置文件和忽略规则
- 添加 Babel 配置文件支持 ES6+ 语法转换 - 添加 ESLint 忽略规则和配置文件 - 添加 Git 忽略规则文件 - 添加 Travis CI 配置文件 - 添加 1.4.2 版本变更日志文件 - 添加 Helm 图表辅助模板文件 - 添加 Helm 忽略规则文件
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.integration.dubbo;
|
||||
|
||||
import io.seata.common.util.StringUtils;
|
||||
import io.seata.core.constants.DubboConstants;
|
||||
import io.seata.core.context.RootContext;
|
||||
import io.seata.core.model.BranchType;
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.rpc.Filter;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.Result;
|
||||
import org.apache.dubbo.rpc.RpcContext;
|
||||
import org.apache.dubbo.rpc.RpcException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The type Transaction propagation filter.
|
||||
*
|
||||
* @author sharajava
|
||||
*/
|
||||
@Activate(group = {DubboConstants.PROVIDER, DubboConstants.CONSUMER}, order = 100)
|
||||
public class ApacheDubboTransactionPropagationFilter implements Filter {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ApacheDubboTransactionPropagationFilter.class);
|
||||
|
||||
@Override
|
||||
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
|
||||
String xid = RootContext.getXID();
|
||||
BranchType branchType = RootContext.getBranchType();
|
||||
|
||||
String rpcXid = getRpcXid();
|
||||
String rpcBranchType = RpcContext.getContext().getAttachment(RootContext.KEY_BRANCH_TYPE);
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("xid in RootContext[{}] xid in RpcContext[{}]", xid, rpcXid);
|
||||
}
|
||||
boolean bind = false;
|
||||
if (xid != null) {
|
||||
RpcContext.getContext().setAttachment(RootContext.KEY_XID, xid);
|
||||
RpcContext.getContext().setAttachment(RootContext.KEY_BRANCH_TYPE, branchType.name());
|
||||
} else {
|
||||
if (rpcXid != null) {
|
||||
RootContext.bind(rpcXid);
|
||||
if (StringUtils.equals(BranchType.TCC.name(), rpcBranchType)) {
|
||||
RootContext.bindBranchType(BranchType.TCC);
|
||||
}
|
||||
bind = true;
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("bind xid [{}] branchType [{}] to RootContext", rpcXid, rpcBranchType);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
return invoker.invoke(invocation);
|
||||
} finally {
|
||||
if (bind) {
|
||||
BranchType previousBranchType = RootContext.getBranchType();
|
||||
String unbindXid = RootContext.unbind();
|
||||
if (BranchType.TCC == previousBranchType) {
|
||||
RootContext.unbindBranchType();
|
||||
}
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("unbind xid [{}] branchType [{}] from RootContext", unbindXid, previousBranchType);
|
||||
}
|
||||
if (!rpcXid.equalsIgnoreCase(unbindXid)) {
|
||||
LOGGER.warn("xid in change during RPC from {} to {},branchType from {} to {}", rpcXid, unbindXid,
|
||||
rpcBranchType != null ? rpcBranchType : "AT", previousBranchType);
|
||||
if (unbindXid != null) {
|
||||
RootContext.bind(unbindXid);
|
||||
LOGGER.warn("bind xid [{}] back to RootContext", unbindXid);
|
||||
if (BranchType.TCC == previousBranchType) {
|
||||
RootContext.bindBranchType(BranchType.TCC);
|
||||
LOGGER.warn("bind branchType [{}] back to RootContext", previousBranchType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get rpc xid
|
||||
* @return
|
||||
*/
|
||||
private String getRpcXid() {
|
||||
String rpcXid = RpcContext.getContext().getAttachment(RootContext.KEY_XID);
|
||||
if (rpcXid == null) {
|
||||
rpcXid = RpcContext.getContext().getAttachment(RootContext.KEY_XID.toLowerCase());
|
||||
}
|
||||
return rpcXid;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
io.seata.integration.dubbo.ApacheDubboTransactionPropagationFilter
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.integration.dubbo;
|
||||
|
||||
import io.seata.core.context.RootContext;
|
||||
import io.seata.core.model.BranchType;
|
||||
import io.seata.integration.dubbo.mock.MockInvoker;
|
||||
import org.apache.dubbo.rpc.RpcContext;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author wang.liang
|
||||
*/
|
||||
public class ApacheDubboTransactionPropagationFilterTest {
|
||||
|
||||
private static final String DEFAULT_XID = "1234567890";
|
||||
|
||||
@Test
|
||||
public void testInvoke_And_RootContext() {
|
||||
ApacheDubboTransactionPropagationFilter filter = new ApacheDubboTransactionPropagationFilter();
|
||||
|
||||
// SAGA
|
||||
RpcContext.getContext().setAttachment(RootContext.KEY_XID, DEFAULT_XID);
|
||||
RpcContext.getContext().setAttachment(RootContext.KEY_BRANCH_TYPE, BranchType.SAGA.name());
|
||||
filter.invoke(new MockInvoker(() -> {
|
||||
assertThat(RootContext.getXID()).isEqualTo(DEFAULT_XID);
|
||||
assertThat(RootContext.getBranchType()).isEqualTo(BranchType.AT);
|
||||
}), null);
|
||||
assertThat(RootContext.unbind()).isNull();
|
||||
assertThat(RootContext.unbindBranchType()).isNull();
|
||||
|
||||
// TCC
|
||||
RpcContext.getContext().setAttachment(RootContext.KEY_XID, DEFAULT_XID);
|
||||
RpcContext.getContext().setAttachment(RootContext.KEY_BRANCH_TYPE, BranchType.TCC.name());
|
||||
filter.invoke(new MockInvoker(() -> {
|
||||
assertThat(RootContext.getXID()).isEqualTo(DEFAULT_XID);
|
||||
assertThat(RootContext.getBranchType()).isEqualTo(BranchType.TCC);
|
||||
}), null);
|
||||
assertThat(RootContext.unbind()).isNull();
|
||||
assertThat(RootContext.unbindBranchType()).isNull();
|
||||
|
||||
// TCC
|
||||
RootContext.bind(DEFAULT_XID);
|
||||
RootContext.bindBranchType(BranchType.SAGA);
|
||||
RpcContext.getContext().setAttachment(RootContext.KEY_XID, DEFAULT_XID);
|
||||
RpcContext.getContext().setAttachment(RootContext.KEY_BRANCH_TYPE, BranchType.TCC.name());
|
||||
filter.invoke(new MockInvoker(() -> {
|
||||
assertThat(RootContext.getXID()).isEqualTo(DEFAULT_XID);
|
||||
assertThat(RootContext.getBranchType()).isEqualTo(BranchType.SAGA);
|
||||
}), null);
|
||||
assertThat(RootContext.unbind()).isEqualTo(DEFAULT_XID);
|
||||
assertThat(RootContext.unbindBranchType()).isEqualTo(BranchType.SAGA);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 1999-2019 Seata.io Group.
|
||||
*
|
||||
* Licensed 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 io.seata.integration.dubbo.mock;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.Result;
|
||||
import org.apache.dubbo.rpc.RpcException;
|
||||
|
||||
/**
|
||||
* @author wang.liang
|
||||
*/
|
||||
public class MockInvoker implements Invoker<Object> {
|
||||
|
||||
private Runnable runnable;
|
||||
|
||||
public MockInvoker() {
|
||||
}
|
||||
|
||||
public MockInvoker(Runnable runnable) {
|
||||
this.runnable = runnable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Object> getInterface() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result invoke(Invocation invocation) throws RpcException {
|
||||
if (runnable != null) {
|
||||
runnable.run();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getUrl() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user