This is an automated email from the ASF dual-hosted git repository.

jianglongtao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 5986a89d20d Add check for `ALTER TRANSACTION RULE` (#22722)
5986a89d20d is described below

commit 5986a89d20de422d5a188b7f64e9427e76574d55
Author: jiangML <[email protected]>
AuthorDate: Thu Dec 8 15:08:44 2022 +0800

    Add check for `ALTER TRANSACTION RULE` (#22722)
    
    * add check for ALTER TRANSACTION RULE
    
    * optimize code
    
    * optimize javadoc
    
    * optimize code
---
 .../rule/InvalidRuleConfigurationException.java    |  4 ++
 .../ShardingSphereTransactionManagerFactory.java   | 17 +++++
 .../spi/ShardingSphereTransactionManager.java      | 10 +++
 .../AlterTransactionRuleStatementUpdater.java      | 38 +++++++++++
 .../ShardingSphereTransactionManagerFixture.java   | 75 ++++++++++++++++++++++
 .../AlterTransactionRuleStatementUpdaterTest.java  | 33 ++++++----
 .../xa/XAShardingSphereTransactionManager.java     |  7 +-
 .../XATransactionManagerProviderFactory.java       | 10 +++
 8 files changed, 181 insertions(+), 13 deletions(-)

diff --git 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/distsql/exception/rule/InvalidRuleConfigurationException.java
 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/distsql/exception/rule/InvalidRuleConfigurationException.java
index b64d3aef87a..3133d6bf252 100644
--- 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/distsql/exception/rule/InvalidRuleConfigurationException.java
+++ 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/distsql/exception/rule/InvalidRuleConfigurationException.java
@@ -35,4 +35,8 @@ public final class InvalidRuleConfigurationException extends 
RuleDefinitionViola
     public InvalidRuleConfigurationException(final String ruleType, final 
Collection<String> rules, final Collection<String> errorMessages) {
         super(XOpenSQLState.CHECK_OPTION_VIOLATION, 100, "Invalid `%s` rules 
`%s`, error messages are: %s", ruleType, rules, errorMessages);
     }
+    
+    public InvalidRuleConfigurationException(final String ruleType, final 
String errorMessage) {
+        super(XOpenSQLState.CHECK_OPTION_VIOLATION, 100, "Invalid `%s` rule, 
error message is: %s", ruleType, errorMessage);
+    }
 }
diff --git 
a/kernel/transaction/api/src/main/java/org/apache/shardingsphere/transaction/factory/ShardingSphereTransactionManagerFactory.java
 
b/kernel/transaction/api/src/main/java/org/apache/shardingsphere/transaction/factory/ShardingSphereTransactionManagerFactory.java
index cd0551091f4..7e11bb08df2 100644
--- 
a/kernel/transaction/api/src/main/java/org/apache/shardingsphere/transaction/factory/ShardingSphereTransactionManagerFactory.java
+++ 
b/kernel/transaction/api/src/main/java/org/apache/shardingsphere/transaction/factory/ShardingSphereTransactionManagerFactory.java
@@ -20,8 +20,11 @@ package org.apache.shardingsphere.transaction.factory;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import org.apache.shardingsphere.infra.util.spi.ShardingSphereServiceLoader;
+import org.apache.shardingsphere.transaction.api.TransactionType;
 import 
org.apache.shardingsphere.transaction.spi.ShardingSphereTransactionManager;
+
 import java.util.Collection;
+import java.util.Optional;
 
 /**
  * ShardingSphere transaction manager factory.
@@ -41,4 +44,18 @@ public final class ShardingSphereTransactionManagerFactory {
     public static Collection<ShardingSphereTransactionManager> 
getAllInstances() {
         return 
ShardingSphereServiceLoader.getServiceInstances(ShardingSphereTransactionManager.class);
     }
+    
+    /**
+     * Get instance of ShardingSphere transaction manager.
+     *
+     * @param transactionType transaction type
+     * @return ShardingSphere transaction manager instance
+     */
+    public static Optional<ShardingSphereTransactionManager> getInstance(final 
TransactionType transactionType) {
+        Collection<ShardingSphereTransactionManager> transactionManagers = 
ShardingSphereTransactionManagerFactory.getAllInstances();
+        if (null == transactionManagers || transactionManagers.isEmpty()) {
+            return Optional.empty();
+        }
+        return transactionManagers.stream().filter(each -> 
transactionType.equals(each.getTransactionType())).findFirst();
+    }
 }
diff --git 
a/kernel/transaction/api/src/main/java/org/apache/shardingsphere/transaction/spi/ShardingSphereTransactionManager.java
 
b/kernel/transaction/api/src/main/java/org/apache/shardingsphere/transaction/spi/ShardingSphereTransactionManager.java
index d6a3ef36487..e610ca3fb45 100644
--- 
a/kernel/transaction/api/src/main/java/org/apache/shardingsphere/transaction/spi/ShardingSphereTransactionManager.java
+++ 
b/kernel/transaction/api/src/main/java/org/apache/shardingsphere/transaction/spi/ShardingSphereTransactionManager.java
@@ -86,4 +86,14 @@ public interface ShardingSphereTransactionManager extends 
AutoCloseable {
      * Rollback transaction.
      */
     void rollback();
+    
+    /**
+     * Judge whether contains the provider type.
+     *
+     * @param providerType transaction manager provider type 
+     * @return contains provider type or not
+     */
+    default boolean containsProviderType(String providerType) {
+        return true;
+    }
 }
diff --git 
a/kernel/transaction/distsql/handler/src/main/java/org/apache/shardingsphere/transaction/distsql/handler/update/AlterTransactionRuleStatementUpdater.java
 
b/kernel/transaction/distsql/handler/src/main/java/org/apache/shardingsphere/transaction/distsql/handler/update/AlterTransactionRuleStatementUpdater.java
index 9662982e1d4..870c2fd48f8 100644
--- 
a/kernel/transaction/distsql/handler/src/main/java/org/apache/shardingsphere/transaction/distsql/handler/update/AlterTransactionRuleStatementUpdater.java
+++ 
b/kernel/transaction/distsql/handler/src/main/java/org/apache/shardingsphere/transaction/distsql/handler/update/AlterTransactionRuleStatementUpdater.java
@@ -17,15 +17,21 @@
 
 package org.apache.shardingsphere.transaction.distsql.handler.update;
 
+import 
org.apache.shardingsphere.infra.distsql.exception.rule.InvalidRuleConfigurationException;
 import org.apache.shardingsphere.infra.distsql.update.GlobalRuleRALUpdater;
 import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
+import 
org.apache.shardingsphere.infra.util.exception.ShardingSpherePreconditions;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
+import org.apache.shardingsphere.transaction.api.TransactionType;
 import 
org.apache.shardingsphere.transaction.config.TransactionRuleConfiguration;
 import 
org.apache.shardingsphere.transaction.distsql.parser.statement.updatable.AlterTransactionRuleStatement;
+import 
org.apache.shardingsphere.transaction.factory.ShardingSphereTransactionManagerFactory;
 import org.apache.shardingsphere.transaction.rule.TransactionRule;
+import 
org.apache.shardingsphere.transaction.spi.ShardingSphereTransactionManager;
 
 import java.util.Collection;
+import java.util.Objects;
 
 /**
  * Alter transaction rule statement handler.
@@ -34,6 +40,7 @@ public final class AlterTransactionRuleStatementUpdater 
implements GlobalRuleRAL
     
     @Override
     public void executeUpdate(final ShardingSphereMetaData metaData, final 
SQLStatement sqlStatement) {
+        check((AlterTransactionRuleStatement) sqlStatement);
         Collection<ShardingSphereRule> globalRules = 
metaData.getGlobalRuleMetaData().getRules();
         globalRules.stream().filter(each -> each instanceof 
TransactionRule).forEach(each -> ((TransactionRule) each).closeStaleResource());
         globalRules.removeIf(each -> each instanceof TransactionRule);
@@ -41,6 +48,37 @@ public final class AlterTransactionRuleStatementUpdater 
implements GlobalRuleRAL
         globalRules.add(new TransactionRule(toBeAlteredRuleConfig, 
metaData.getDatabases()));
     }
     
+    private void check(final AlterTransactionRuleStatement statement) {
+        checkTransactionType(statement);
+        TransactionType transactionType = 
TransactionType.valueOf(statement.getDefaultType().toUpperCase());
+        if (TransactionType.LOCAL.equals(transactionType)) {
+            return;
+        }
+        checkTransactionManager(statement, transactionType);
+    }
+    
+    private void checkTransactionType(final AlterTransactionRuleStatement 
statement) {
+        try {
+            TransactionType.valueOf(statement.getDefaultType().toUpperCase());
+        } catch (final IllegalArgumentException ex) {
+            throw new InvalidRuleConfigurationException("Transaction", 
String.format("Unsupported transaction type `%s`", statement.getDefaultType()));
+        }
+    }
+    
+    private void checkTransactionManager(final AlterTransactionRuleStatement 
statement, final TransactionType transactionType) {
+        ShardingSphereTransactionManager transactionManager = 
ShardingSphereTransactionManagerFactory.getInstance(transactionType).orElse(null);
+        
ShardingSpherePreconditions.checkState(Objects.nonNull(transactionManager),
+                () -> new InvalidRuleConfigurationException("Transaction", 
String.format("No transaction manager with type `%s`", 
statement.getDefaultType())));
+        if (TransactionType.XA.equals(transactionType)) {
+            checkTransactionManagerProviderType(transactionManager, 
statement.getProvider().getProviderType());
+        }
+    }
+    
+    private void checkTransactionManagerProviderType(final 
ShardingSphereTransactionManager transactionManager, final String providerType) 
{
+        
ShardingSpherePreconditions.checkState(transactionManager.containsProviderType(providerType),
+                () -> new InvalidRuleConfigurationException("Transaction", 
String.format("No transaction manager provider with type `%s`", providerType)));
+    }
+    
     private TransactionRuleConfiguration 
createToBeAlteredRuleConfiguration(final SQLStatement sqlStatement) {
         AlterTransactionRuleStatement ruleStatement = 
(AlterTransactionRuleStatement) sqlStatement;
         return new 
TransactionRuleConfiguration(ruleStatement.getDefaultType(), 
ruleStatement.getProvider().getProviderType(), 
ruleStatement.getProvider().getProps());
diff --git 
a/kernel/transaction/distsql/handler/src/test/java/org/apache/shardingsphere/transaction/distsql/handler/fixture/ShardingSphereTransactionManagerFixture.java
 
b/kernel/transaction/distsql/handler/src/test/java/org/apache/shardingsphere/transaction/distsql/handler/fixture/ShardingSphereTransactionManagerFixture.java
new file mode 100644
index 00000000000..480507c7136
--- /dev/null
+++ 
b/kernel/transaction/distsql/handler/src/test/java/org/apache/shardingsphere/transaction/distsql/handler/fixture/ShardingSphereTransactionManagerFixture.java
@@ -0,0 +1,75 @@
+/*
+ * 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.shardingsphere.transaction.distsql.handler.fixture;
+
+import lombok.Setter;
+import org.apache.shardingsphere.infra.database.type.DatabaseType;
+import org.apache.shardingsphere.transaction.api.TransactionType;
+import 
org.apache.shardingsphere.transaction.spi.ShardingSphereTransactionManager;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.util.Map;
+
+public class ShardingSphereTransactionManagerFixture implements 
ShardingSphereTransactionManager {
+    
+    @Setter
+    private Runnable caller;
+    
+    @Override
+    public void init(final Map<String, DatabaseType> databaseTypes, final 
Map<String, DataSource> dataSources, final String providerType) {
+        if (null != caller) {
+            caller.run();
+        }
+    }
+    
+    @Override
+    public TransactionType getTransactionType() {
+        return TransactionType.XA;
+    }
+    
+    @Override
+    public boolean isInTransaction() {
+        return true;
+    }
+    
+    @Override
+    public Connection getConnection(final String databaseName, final String 
dataSourceName) {
+        return null;
+    }
+    
+    @Override
+    public void begin() {
+    }
+    
+    @Override
+    public void begin(final int timeout) {
+    }
+    
+    @Override
+    public void commit(final boolean rollbackOnly) {
+    }
+    
+    @Override
+    public void rollback() {
+    }
+    
+    @Override
+    public void close() {
+    }
+}
diff --git 
a/kernel/transaction/distsql/handler/src/test/java/org/apache/shardingsphere/transaction/distsql/handler/update/AlterTransactionRuleStatementUpdaterTest.java
 
b/kernel/transaction/distsql/handler/src/test/java/org/apache/shardingsphere/transaction/distsql/handler/update/AlterTransactionRuleStatementUpdaterTest.java
index d21a41d323a..f2bb290a96c 100644
--- 
a/kernel/transaction/distsql/handler/src/test/java/org/apache/shardingsphere/transaction/distsql/handler/update/AlterTransactionRuleStatementUpdaterTest.java
+++ 
b/kernel/transaction/distsql/handler/src/test/java/org/apache/shardingsphere/transaction/distsql/handler/update/AlterTransactionRuleStatementUpdaterTest.java
@@ -22,42 +22,51 @@ import 
org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import 
org.apache.shardingsphere.infra.metadata.database.rule.ShardingSphereRuleMetaData;
 import org.apache.shardingsphere.infra.util.props.PropertiesConverter;
-import 
org.apache.shardingsphere.transaction.config.TransactionRuleConfiguration;
 import org.apache.shardingsphere.transaction.api.TransactionType;
+import 
org.apache.shardingsphere.transaction.config.TransactionRuleConfiguration;
+import 
org.apache.shardingsphere.transaction.distsql.handler.fixture.ShardingSphereTransactionManagerFixture;
 import 
org.apache.shardingsphere.transaction.distsql.parser.segment.TransactionProviderSegment;
 import 
org.apache.shardingsphere.transaction.distsql.parser.statement.updatable.AlterTransactionRuleStatement;
+import 
org.apache.shardingsphere.transaction.factory.ShardingSphereTransactionManagerFactory;
 import org.apache.shardingsphere.transaction.rule.TransactionRule;
 import org.junit.Test;
+import org.mockito.MockedStatic;
 
 import javax.sql.DataSource;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Properties;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
 import static org.mockito.Mockito.when;
 
 public final class AlterTransactionRuleStatementUpdaterTest {
     
     @Test
     public void assertExecuteWithXA() {
-        AlterTransactionRuleStatementUpdater updater = new 
AlterTransactionRuleStatementUpdater();
-        ShardingSphereMetaData metaData = createMetaData();
-        updater.executeUpdate(metaData, new 
AlterTransactionRuleStatement("XA", new TransactionProviderSegment("Atomikos", 
createProperties())));
-        TransactionRule updatedRule = 
metaData.getGlobalRuleMetaData().getSingleRule(TransactionRule.class);
-        assertThat(updatedRule.getDefaultType(), is(TransactionType.XA));
-        assertThat(updatedRule.getProviderType(), is("Atomikos"));
-        assertTrue(updatedRule.getDatabases().containsKey("foo_db"));
-        assertTrue(null != updatedRule.getProps() && 
!updatedRule.getProps().isEmpty());
-        String props = PropertiesConverter.convert(updatedRule.getProps());
-        assertTrue(props.contains("host=127.0.0.1"));
-        assertTrue(props.contains("databaseName=jbossts"));
+        try (MockedStatic<ShardingSphereTransactionManagerFactory> mockFactory 
= mockStatic(ShardingSphereTransactionManagerFactory.class)) {
+            mockFactory.when(() -> 
ShardingSphereTransactionManagerFactory.getInstance(any())).thenReturn(Optional.of(new
 ShardingSphereTransactionManagerFixture()));
+            AlterTransactionRuleStatementUpdater updater = new 
AlterTransactionRuleStatementUpdater();
+            ShardingSphereMetaData metaData = createMetaData();
+            updater.executeUpdate(metaData, new 
AlterTransactionRuleStatement("XA", new TransactionProviderSegment("Atomikos", 
createProperties())));
+            TransactionRule updatedRule = 
metaData.getGlobalRuleMetaData().getSingleRule(TransactionRule.class);
+            assertThat(updatedRule.getDefaultType(), is(TransactionType.XA));
+            assertThat(updatedRule.getProviderType(), is("Atomikos"));
+            assertTrue(updatedRule.getDatabases().containsKey("foo_db"));
+            assertTrue(null != updatedRule.getProps() && 
!updatedRule.getProps().isEmpty());
+            String props = PropertiesConverter.convert(updatedRule.getProps());
+            assertTrue(props.contains("host=127.0.0.1"));
+            assertTrue(props.contains("databaseName=jbossts"));
+        }
     }
     
     @Test
diff --git 
a/kernel/transaction/type/xa/core/src/main/java/org/apache/shardingsphere/transaction/xa/XAShardingSphereTransactionManager.java
 
b/kernel/transaction/type/xa/core/src/main/java/org/apache/shardingsphere/transaction/xa/XAShardingSphereTransactionManager.java
index 370054c8564..7127fefb660 100644
--- 
a/kernel/transaction/type/xa/core/src/main/java/org/apache/shardingsphere/transaction/xa/XAShardingSphereTransactionManager.java
+++ 
b/kernel/transaction/type/xa/core/src/main/java/org/apache/shardingsphere/transaction/xa/XAShardingSphereTransactionManager.java
@@ -19,8 +19,8 @@ package org.apache.shardingsphere.transaction.xa;
 
 import lombok.SneakyThrows;
 import org.apache.shardingsphere.infra.database.type.DatabaseType;
-import org.apache.shardingsphere.transaction.core.ResourceDataSource;
 import org.apache.shardingsphere.transaction.api.TransactionType;
+import org.apache.shardingsphere.transaction.core.ResourceDataSource;
 import 
org.apache.shardingsphere.transaction.spi.ShardingSphereTransactionManager;
 import 
org.apache.shardingsphere.transaction.xa.jta.datasource.XATransactionDataSource;
 import 
org.apache.shardingsphere.transaction.xa.manager.XATransactionManagerProviderFactory;
@@ -135,4 +135,9 @@ public final class XAShardingSphereTransactionManager 
implements ShardingSphereT
             xaTransactionManagerProvider.close();
         }
     }
+    
+    @Override
+    public boolean containsProviderType(final String providerType) {
+        return XATransactionManagerProviderFactory.contains(providerType);
+    }
 }
diff --git 
a/kernel/transaction/type/xa/core/src/main/java/org/apache/shardingsphere/transaction/xa/manager/XATransactionManagerProviderFactory.java
 
b/kernel/transaction/type/xa/core/src/main/java/org/apache/shardingsphere/transaction/xa/manager/XATransactionManagerProviderFactory.java
index a08bcf9282d..4ceaa037d8b 100644
--- 
a/kernel/transaction/type/xa/core/src/main/java/org/apache/shardingsphere/transaction/xa/manager/XATransactionManagerProviderFactory.java
+++ 
b/kernel/transaction/type/xa/core/src/main/java/org/apache/shardingsphere/transaction/xa/manager/XATransactionManagerProviderFactory.java
@@ -47,4 +47,14 @@ public final class XATransactionManagerProviderFactory {
                 ? 
RequiredSPIRegistry.getRegisteredService(XATransactionManagerProvider.class)
                 : 
TypedSPIRegistry.getRegisteredService(XATransactionManagerProvider.class, type, 
new Properties());
     }
+    
+    /**
+     * Judge whether contains XA transaction manager provider.
+     *
+     * @param type XA transaction manager provider type
+     * @return contains XA transaction manager provider or not
+     */
+    public static boolean contains(final String type) {
+        return 
TypedSPIRegistry.findRegisteredService(XATransactionManagerProvider.class, 
type).isPresent();
+    }
 }

Reply via email to