This is an automated email from the ASF dual-hosted git repository. jianbin pushed a commit to branch 2.x in repository https://gitbox.apache.org/repos/asf/incubator-seata.git
The following commit(s) were added to refs/heads/2.x by this push: new 1076e2b3c0 optimize: Prohibit registration of TCC resources with the same name (#6391) 1076e2b3c0 is described below commit 1076e2b3c07e01b88cc5b99dc45f68e168356587 Author: yiqi <77573225+pleasegivemethec...@users.noreply.github.com> AuthorDate: Tue Mar 5 21:33:30 2024 +0800 optimize: Prohibit registration of TCC resources with the same name (#6391) --- changes/en-us/2.x.md | 1 + changes/zh-cn/2.x.md | 2 +- .../exception/RepeatRegistrationException.java | 51 ++++++++++++++++++++++ .../AdapterSpringSeataInterceptorTest.java | 23 ++++++---- .../apache/seata/rm/tcc/TCCResourceManager.java | 32 +++++++++++--- .../org/apache/seata/rm/tcc/NestTccAction.java | 2 +- .../org/apache/seata/rm/tcc/NormalTccAction.java | 2 +- .../rm/tcc/interceptor/ProxyUtilsTccTest.java | 23 +++++----- .../parser/TccActionInterceptorParserTest.java | 6 +++ .../core/rpc/netty/mockserver/RmClientTest.java | 1 + 10 files changed, 115 insertions(+), 28 deletions(-) diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md index fa5ebb56ef..ba6d1b1d3d 100644 --- a/changes/en-us/2.x.md +++ b/changes/en-us/2.x.md @@ -104,6 +104,7 @@ Add changes here for all PR submitted to the 2.x branch. - [[#6366](https://github.com/apache/incubator-seata/pull/6366)] optimized globaltransaction compatibility issues - [[#6369](https://github.com/apache/incubator-seata/pull/6369)] optimize arm64 ci - [[#6386](https://github.com/apache/incubator-seata/pull/6386)] replace `byte-buddy` to JDK proxy in `ConfigurationCache` +- [[#6391](https://github.com/apache/incubator-seata/pull/6091)] forbid duplicate registration of TCC resources ### refactor: - [[#6269](https://github.com/apache/incubator-seata/pull/6269)] standardize Seata Exception diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md index 5c7ff19985..446dd5558e 100644 --- a/changes/zh-cn/2.x.md +++ b/changes/zh-cn/2.x.md @@ -108,7 +108,7 @@ - [[#6366](https://github.com/apache/incubator-seata/pull/6366)] 优化globaltransaction向下兼容性 - [[#6369](https://github.com/apache/incubator-seata/pull/6369)] 优化 arm64 ci - [[#6386](https://github.com/apache/incubator-seata/pull/6386)] 在 `ConfigurationCache` 类中,将 `byte-buddy` 替换为JDK代理 - +- [[#6391](https://github.com/apache/incubator-seata/pull/6091)] 禁止重复注册TCC资源 ### refactor: diff --git a/common/src/main/java/org/apache/seata/common/exception/RepeatRegistrationException.java b/common/src/main/java/org/apache/seata/common/exception/RepeatRegistrationException.java new file mode 100644 index 0000000000..127d544c9c --- /dev/null +++ b/common/src/main/java/org/apache/seata/common/exception/RepeatRegistrationException.java @@ -0,0 +1,51 @@ +/* + * 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.seata.common.exception; + +/** + * The repeat registration exception. + */ +public class RepeatRegistrationException extends RuntimeException { + + /** + * Instantiates a new RepeatRegistrationException. + * + * @param message the message + */ + public RepeatRegistrationException(String message) { + super(message); + } + + /** + * Instantiates a new RepeatRegistrationException. + * + * @param message the message + * @param cause the cause + */ + public RepeatRegistrationException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Instantiates a new RepeatRegistrationException. + * + * @param cause the cause + */ + public RepeatRegistrationException(Throwable cause) { + super(cause); + } +} \ No newline at end of file diff --git a/spring/src/test/java/org/apache/seata/spring/annotation/AdapterSpringSeataInterceptorTest.java b/spring/src/test/java/org/apache/seata/spring/annotation/AdapterSpringSeataInterceptorTest.java index da8fc35961..e1d0e19e48 100644 --- a/spring/src/test/java/org/apache/seata/spring/annotation/AdapterSpringSeataInterceptorTest.java +++ b/spring/src/test/java/org/apache/seata/spring/annotation/AdapterSpringSeataInterceptorTest.java @@ -29,6 +29,7 @@ import org.apache.seata.spring.tcc.NormalTccAction; import org.apache.seata.spring.tcc.NormalTccActionImpl; import org.aopalliance.intercept.MethodInvocation; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; /** @@ -36,12 +37,20 @@ import org.junit.jupiter.api.Test; */ class AdapterSpringSeataInterceptorTest { - @Test - void should_throw_raw_exception_when_call_prepareWithException() throws Throwable { + private static NormalTccAction normalTccAction; + + private static AdapterSpringSeataInterceptor adapterSpringSeataInterceptor; + + @BeforeAll + static void init() throws Throwable { //given - NormalTccActionImpl normalTccAction = new NormalTccActionImpl(); + normalTccAction = new NormalTccActionImpl(); ProxyInvocationHandler proxyInvocationHandler = DefaultInterfaceParser.get().parserInterfaceToProxy(normalTccAction, "proxyTccAction"); - AdapterSpringSeataInterceptor adapterSpringSeataInterceptor = new AdapterSpringSeataInterceptor(proxyInvocationHandler); + adapterSpringSeataInterceptor = new AdapterSpringSeataInterceptor(proxyInvocationHandler); + } + + @Test + void should_throw_raw_exception_when_call_prepareWithException() throws Throwable { MyMockMethodInvocation myMockMethodInvocation = new MyMockMethodInvocation(NormalTccAction.class.getMethod("prepareWithException", BusinessActionContext.class), () -> normalTccAction.prepareWithException(null)); //when then @@ -50,10 +59,6 @@ class AdapterSpringSeataInterceptorTest { @Test void should_success_when_call_prepare_with_ProxyInvocationHandler() throws Throwable { - //given - NormalTccActionImpl normalTccAction = new NormalTccActionImpl(); - ProxyInvocationHandler proxyInvocationHandler = DefaultInterfaceParser.get().parserInterfaceToProxy(normalTccAction, "proxyTccAction"); - AdapterSpringSeataInterceptor adapterSpringSeataInterceptor = new AdapterSpringSeataInterceptor(proxyInvocationHandler); MyMockMethodInvocation myMockMethodInvocation = new MyMockMethodInvocation(NormalTccAction.class.getMethod("prepare", BusinessActionContext.class), () -> normalTccAction.prepare(null)); //when then @@ -100,4 +105,4 @@ class AdapterSpringSeataInterceptorTest { return null; } } -} +} \ No newline at end of file diff --git a/tcc/src/main/java/org/apache/seata/rm/tcc/TCCResourceManager.java b/tcc/src/main/java/org/apache/seata/rm/tcc/TCCResourceManager.java index 83c1d70e5c..c19f08604c 100644 --- a/tcc/src/main/java/org/apache/seata/rm/tcc/TCCResourceManager.java +++ b/tcc/src/main/java/org/apache/seata/rm/tcc/TCCResourceManager.java @@ -22,6 +22,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.seata.common.Constants; +import org.apache.seata.common.exception.RepeatRegistrationException; import org.apache.seata.common.exception.ShouldNeverHappenException; import org.apache.seata.common.exception.SkipCallbackWrapperException; import org.apache.seata.core.exception.TransactionException; @@ -59,16 +60,35 @@ public class TCCResourceManager extends AbstractResourceManager { */ @Override public void registerResource(Resource resource) { - TCCResource tccResource = (TCCResource)resource; - tccResourceCache.put(tccResource.getResourceId(), tccResource); - super.registerResource(tccResource); + String resourceId = resource.getResourceId(); + TCCResource newResource = (TCCResource) resource; + TCCResource oldResource = getTCCResource(resourceId); + + if (oldResource != null) { + Object newResourceBean = newResource.getTargetBean(); + Object oldResourceBean = oldResource.getTargetBean(); + if (newResourceBean != oldResourceBean) { + throw new RepeatRegistrationException(String.format("Same TCC resource name <%s> between method1 <%s> of class1 <%s> and method2 <%s> of class2 <%s>, should be unique", + resourceId, + newResource.getPrepareMethod().getName(), + newResourceBean.getClass().getName(), + oldResource.getPrepareMethod().getName(), + oldResourceBean.getClass().getName())); + } + } + + tccResourceCache.put(resourceId, newResource); + super.registerResource(newResource); + } + + public TCCResource getTCCResource(String resourceId) { + return (TCCResource) tccResourceCache.get(resourceId); } @Override public Map<String, Resource> getManagedResources() { return tccResourceCache; } - /** * TCC branch commit * @@ -83,7 +103,7 @@ public class TCCResourceManager extends AbstractResourceManager { @Override public BranchStatus branchCommit(BranchType branchType, String xid, long branchId, String resourceId, String applicationData) throws TransactionException { - TCCResource tccResource = (TCCResource)tccResourceCache.get(resourceId); + TCCResource tccResource = getTCCResource(resourceId); if (tccResource == null) { throw new ShouldNeverHappenException(String.format("TCC resource is not exist, resourceId: %s", resourceId)); } @@ -142,7 +162,7 @@ public class TCCResourceManager extends AbstractResourceManager { @Override public BranchStatus branchRollback(BranchType branchType, String xid, long branchId, String resourceId, String applicationData) throws TransactionException { - TCCResource tccResource = (TCCResource)tccResourceCache.get(resourceId); + TCCResource tccResource = getTCCResource(resourceId); if (tccResource == null) { throw new ShouldNeverHappenException(String.format("TCC resource is not exist, resourceId: %s", resourceId)); } diff --git a/tcc/src/test/java/org/apache/seata/rm/tcc/NestTccAction.java b/tcc/src/test/java/org/apache/seata/rm/tcc/NestTccAction.java index 19fe35a8f8..3cd40fc85a 100644 --- a/tcc/src/test/java/org/apache/seata/rm/tcc/NestTccAction.java +++ b/tcc/src/test/java/org/apache/seata/rm/tcc/NestTccAction.java @@ -35,7 +35,7 @@ public interface NestTccAction { @TwoPhaseBusinessAction(name = "tccNestActionForTest") boolean prepare(BusinessActionContext actionContext, int count); - @TwoPhaseBusinessAction(name = "tccNestActionForTest") + @TwoPhaseBusinessAction(name = "tccNestActionRequiredNewForTest") boolean prepareNestRequiredNew(BusinessActionContext actionContext, int count); /** diff --git a/tcc/src/test/java/org/apache/seata/rm/tcc/NormalTccAction.java b/tcc/src/test/java/org/apache/seata/rm/tcc/NormalTccAction.java index 8fccb820be..a2c44f7816 100644 --- a/tcc/src/test/java/org/apache/seata/rm/tcc/NormalTccAction.java +++ b/tcc/src/test/java/org/apache/seata/rm/tcc/NormalTccAction.java @@ -39,7 +39,7 @@ public interface NormalTccAction { * @param tccParam the tcc param * @return the boolean */ - @TwoPhaseBusinessAction(name = "tccActionForTest", commitMethod = "commit", rollbackMethod = "rollback", commitArgsClasses = {BusinessActionContext.class, TccParam.class}, rollbackArgsClasses = {BusinessActionContext.class, TccParam.class}) + @TwoPhaseBusinessAction(name = "normalTccActionForTest", commitMethod = "commit", rollbackMethod = "rollback", commitArgsClasses = {BusinessActionContext.class, TccParam.class}, rollbackArgsClasses = {BusinessActionContext.class, TccParam.class}) String prepare(BusinessActionContext actionContext, @BusinessActionContextParameter("a") int a, @BusinessActionContextParameter(paramName = "b", index = 0) List b, diff --git a/tcc/src/test/java/org/apache/seata/rm/tcc/interceptor/ProxyUtilsTccTest.java b/tcc/src/test/java/org/apache/seata/rm/tcc/interceptor/ProxyUtilsTccTest.java index 9a243733e9..87fb8083b1 100644 --- a/tcc/src/test/java/org/apache/seata/rm/tcc/interceptor/ProxyUtilsTccTest.java +++ b/tcc/src/test/java/org/apache/seata/rm/tcc/interceptor/ProxyUtilsTccTest.java @@ -16,6 +16,7 @@ */ package org.apache.seata.rm.tcc.interceptor; +import java.io.IOException; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -30,10 +31,10 @@ import org.apache.seata.core.model.Resource; import org.apache.seata.core.model.ResourceManager; import org.apache.seata.integration.tx.api.util.ProxyUtil; import org.apache.seata.rm.DefaultResourceManager; -import org.apache.seata.rm.tcc.NormalTccAction; import org.apache.seata.rm.tcc.NormalTccActionImpl; import org.apache.seata.rm.tcc.TccParam; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -41,6 +42,10 @@ public class ProxyUtilsTccTest { private final String DEFAULT_XID = "default_xid"; + private static NormalTccActionImpl tccAction; + + private static NormalTccActionImpl tccActionProxy; + AtomicReference<String> branchReference = new AtomicReference<String>(); @@ -100,12 +105,16 @@ public class ProxyUtilsTccTest { }; + @BeforeAll + public static void init() throws IOException { + tccAction = new NormalTccActionImpl(); + tccActionProxy = ProxyUtil.createProxy(tccAction); + } + @Test public void testTcc() { //given - NormalTccActionImpl tccAction = new NormalTccActionImpl(); - NormalTccAction tccActionProxy = ProxyUtil.createProxy(tccAction); RootContext.bind(DEFAULT_XID); TccParam tccParam = new TccParam(1, "a...@163.com"); @@ -119,14 +128,12 @@ public class ProxyUtilsTccTest { //then Assertions.assertEquals("a", result); Assertions.assertNotNull(result); - Assertions.assertEquals("tccActionForTest", branchReference.get()); + Assertions.assertEquals("normalTccActionForTest", branchReference.get()); } @Test public void testTccThrowRawException() { //given - NormalTccActionImpl tccAction = new NormalTccActionImpl(); - NormalTccAction tccActionProxy = ProxyUtil.createProxy(tccAction); RootContext.bind(DEFAULT_XID); TccParam tccParam = new TccParam(1, "a...@163.com"); @@ -141,11 +148,7 @@ public class ProxyUtilsTccTest { @Test public void testTccImplementOtherMethod(){ - NormalTccActionImpl tccAction = new NormalTccActionImpl(); - NormalTccActionImpl tccActionProxy = ProxyUtil.createProxy(tccAction); - Assertions.assertTrue(tccActionProxy.otherMethod()); - } diff --git a/tcc/src/test/java/org/apache/seata/rm/tcc/interceptor/parser/TccActionInterceptorParserTest.java b/tcc/src/test/java/org/apache/seata/rm/tcc/interceptor/parser/TccActionInterceptorParserTest.java index 0f19353553..867b9c2de9 100644 --- a/tcc/src/test/java/org/apache/seata/rm/tcc/interceptor/parser/TccActionInterceptorParserTest.java +++ b/tcc/src/test/java/org/apache/seata/rm/tcc/interceptor/parser/TccActionInterceptorParserTest.java @@ -43,6 +43,7 @@ import org.apache.seata.rm.tcc.TccActionImpl; import org.apache.seata.tm.TransactionManagerHolder; import org.apache.seata.tm.api.GlobalTransaction; import org.apache.seata.tm.api.GlobalTransactionContext; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -58,6 +59,11 @@ class TccActionInterceptorParserTest { System.setProperty("service.vgroupMapping.default_tx_group", "default"); } + @AfterEach + public void clearTccResource(){ + resourceManager.getManagedResources().clear(); + } + @Test void parserInterfaceToProxy() { diff --git a/test/src/test/java/org/apache/seata/core/rpc/netty/mockserver/RmClientTest.java b/test/src/test/java/org/apache/seata/core/rpc/netty/mockserver/RmClientTest.java index fcfb0a9052..671f1d4431 100644 --- a/test/src/test/java/org/apache/seata/core/rpc/netty/mockserver/RmClientTest.java +++ b/test/src/test/java/org/apache/seata/core/rpc/netty/mockserver/RmClientTest.java @@ -78,6 +78,7 @@ public class RmClientTest { public static DefaultResourceManager getRm(String resourceId) { RMClient.init(ProtocolTestConstants.APPLICATION_ID, ProtocolTestConstants.SERVICE_GROUP); DefaultResourceManager rm = DefaultResourceManager.get(); + rm.getResourceManager(BranchType.TCC).getManagedResources().clear(); //register:TYPE_REG_RM = 103 , TYPE_REG_RM_RESULT = 104 Action1 target = new Action1Impl(); --------------------------------------------------------------------- To unsubscribe, e-mail: notifications-unsubscr...@seata.apache.org For additional commands, e-mail: notifications-h...@seata.apache.org