This is an automated email from the ASF dual-hosted git repository. wuweijie 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 88e8b5ca3be Multiple types of databases are not supported (#19595) 88e8b5ca3be is described below commit 88e8b5ca3bebada341fa6ada384351df8711b755 Author: JingShang Lu <jingshang...@gmail.com> AuthorDate: Thu Jul 28 10:57:11 2022 +0800 Multiple types of databases are not supported (#19595) * get database type from jdbcUrl --- .../props/DataSourcePropertiesValidator.java | 8 +++- .../transaction/rule/TransactionRule.java | 17 +++++-- .../transaction/rule/TransactionRuleTest.java | 53 ++++++++++++++++++++++ .../rdl/resource/AddResourceBackendHandler.java | 3 +- 4 files changed, 74 insertions(+), 7 deletions(-) diff --git a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/datasource/props/DataSourcePropertiesValidator.java b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/datasource/props/DataSourcePropertiesValidator.java index 3f457f4f970..90cd707496c 100644 --- a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/datasource/props/DataSourcePropertiesValidator.java +++ b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/datasource/props/DataSourcePropertiesValidator.java @@ -18,11 +18,13 @@ package org.apache.shardingsphere.infra.datasource.props; import org.apache.shardingsphere.infra.database.type.DatabaseType; +import org.apache.shardingsphere.infra.database.type.DatabaseTypeEngine; import org.apache.shardingsphere.infra.datasource.pool.creator.DataSourcePoolCreator; import org.apache.shardingsphere.infra.datasource.pool.destroyer.DataSourcePoolDestroyer; import org.apache.shardingsphere.infra.distsql.exception.resource.InvalidResourcesException; import javax.sql.DataSource; +import java.sql.Connection; import java.sql.SQLException; import java.util.Collection; import java.util.LinkedList; @@ -72,8 +74,10 @@ public final class DataSourcePropertiesValidator { } private void checkFailFast(final DataSource dataSource, final DatabaseType databaseType) throws SQLException { - if (!dataSource.getConnection().getMetaData().getDatabaseProductName().equals(databaseType.getType())) { - throw new SQLException("Protocol mismatch for data source."); + try (Connection connection = dataSource.getConnection()) { + if (null != databaseType && !DatabaseTypeEngine.getDatabaseType(connection.getMetaData().getURL()).getType().equals(databaseType.getType())) { + throw new SQLException("Protocol mismatch for data source."); + } } } } diff --git a/shardingsphere-kernel/shardingsphere-transaction/shardingsphere-transaction-core/src/main/java/org/apache/shardingsphere/transaction/rule/TransactionRule.java b/shardingsphere-kernel/shardingsphere-transaction/shardingsphere-transaction-core/src/main/java/org/apache/shardingsphere/transaction/rule/TransactionRule.java index 83738c8dd1d..9749083bc2f 100644 --- a/shardingsphere-kernel/shardingsphere-transaction/shardingsphere-transaction-core/src/main/java/org/apache/shardingsphere/transaction/rule/TransactionRule.java +++ b/shardingsphere-kernel/shardingsphere-transaction/shardingsphere-transaction-core/src/main/java/org/apache/shardingsphere/transaction/rule/TransactionRule.java @@ -17,6 +17,7 @@ package org.apache.shardingsphere.transaction.rule; +import com.google.common.base.Preconditions; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.apache.shardingsphere.infra.database.type.DatabaseType; @@ -30,9 +31,11 @@ import org.apache.shardingsphere.transaction.core.TransactionType; import javax.sql.DataSource; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; +import java.util.Set; /** * Transaction rule. @@ -66,14 +69,20 @@ public final class TransactionRule implements GlobalRule, ResourceHeldRule<Shard if (databases.isEmpty()) { return new ShardingSphereTransactionManagerEngine(); } - ShardingSphereTransactionManagerEngine result = new ShardingSphereTransactionManagerEngine(); Map<String, DataSource> dataSourceMap = new HashMap<>(databases.size()); - DatabaseType databaseType = null; + Set<DatabaseType> databaseTypes = new HashSet<>(); for (Entry<String, ShardingSphereDatabase> entry : databases.entrySet()) { dataSourceMap.putAll(entry.getValue().getResource().getDataSources()); - databaseType = entry.getValue().getProtocolType(); + if (null != entry.getValue().getResource().getDatabaseType()) { + databaseTypes.add(entry.getValue().getResource().getDatabaseType()); + } + } + Preconditions.checkState(databaseTypes.size() < 2, "Multiple types of databases are not supported"); + if (dataSourceMap.isEmpty()) { + return new ShardingSphereTransactionManagerEngine(); } - result.init(databaseType, dataSourceMap, providerType); + ShardingSphereTransactionManagerEngine result = new ShardingSphereTransactionManagerEngine(); + result.init(databaseTypes.iterator().next(), dataSourceMap, providerType); return result; } diff --git a/shardingsphere-kernel/shardingsphere-transaction/shardingsphere-transaction-core/src/test/java/org/apache/shardingsphere/transaction/rule/TransactionRuleTest.java b/shardingsphere-kernel/shardingsphere-transaction/shardingsphere-transaction-core/src/test/java/org/apache/shardingsphere/transaction/rule/TransactionRuleTest.java new file mode 100644 index 00000000000..eb97f653f2a --- /dev/null +++ b/shardingsphere-kernel/shardingsphere-transaction/shardingsphere-transaction-core/src/test/java/org/apache/shardingsphere/transaction/rule/TransactionRuleTest.java @@ -0,0 +1,53 @@ +/* + * 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.rule; + +import org.apache.shardingsphere.infra.database.type.dialect.OpenGaussDatabaseType; +import org.apache.shardingsphere.infra.database.type.dialect.PostgreSQLDatabaseType; +import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; +import org.apache.shardingsphere.infra.metadata.database.resource.ShardingSphereResource; +import org.apache.shardingsphere.transaction.config.TransactionRuleConfiguration; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public final class TransactionRuleTest { + + @Test(expected = IllegalStateException.class) + public void assertMultiDatabaseTypeFail() { + TransactionRuleConfiguration transactionRuleConfiguration = mock(TransactionRuleConfiguration.class); + when(transactionRuleConfiguration.getDefaultType()).thenReturn("XA"); + when(transactionRuleConfiguration.getProviderType()).thenReturn("Atomikos"); + ShardingSphereDatabase db1 = mock(ShardingSphereDatabase.class); + ShardingSphereResource resource1 = mock(ShardingSphereResource.class); + when(resource1.getDatabaseType()).thenReturn(new OpenGaussDatabaseType()); + when(db1.getResource()).thenReturn(resource1); + ShardingSphereDatabase db2 = mock(ShardingSphereDatabase.class); + ShardingSphereResource resource2 = mock(ShardingSphereResource.class); + when(resource2.getDatabaseType()).thenReturn(new PostgreSQLDatabaseType()); + when(db2.getResource()).thenReturn(resource2); + Map<String, ShardingSphereDatabase> databaseMap = new HashMap<>(); + databaseMap.put("db1", db1); + databaseMap.put("db2", db2); + TransactionRule transactionRule = new TransactionRule(transactionRuleConfiguration, databaseMap, null); + } +} diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AddResourceBackendHandler.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AddResourceBackendHandler.java index 07f687b27b2..e37cabe94dd 100644 --- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AddResourceBackendHandler.java +++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AddResourceBackendHandler.java @@ -60,7 +60,8 @@ public final class AddResourceBackendHandler extends DatabaseRequiredBackendHand public ResponseHeader execute(final String databaseName, final AddResourceStatement sqlStatement) throws DistSQLException { checkSQLStatement(databaseName, sqlStatement); Map<String, DataSourceProperties> dataSourcePropsMap = ResourceSegmentsConverter.convert(databaseType, sqlStatement.getDataSources()); - validator.validate(dataSourcePropsMap, databaseType); + DatabaseType storeType = ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getDatabase(databaseName).getResource().getDatabaseType(); + validator.validate(dataSourcePropsMap, storeType); try { ProxyContext.getInstance().getContextManager().updateResources(databaseName, dataSourcePropsMap); } catch (final SQLException | ShardingSphereException ex) {