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();
+ }
}