diff --git a/pom.xml b/pom.xml index d112f36fefc5fe787ce7555f1ddef7a954269897..e0968ce7cecf5ba9c98b8873f4ace40999788cb1 100644 --- a/pom.xml +++ b/pom.xml @@ -93,7 +93,8 @@ 5.1.47 42.2.5 6.1.7.jre7-preview - + 2.4.2 + 3.3 3.1.0 2.7 @@ -291,6 +292,12 @@ ${mysql-connector-java.version} provided + + org.mariadb.jdbc + mariadb-java-client + ${mariadb-java-client.version} + provided + org.postgresql postgresql diff --git a/sharding-core/sharding-core-common/src/main/java/org/apache/shardingsphere/core/metadata/datasource/dialect/MariaDBDataSourceMetaData.java b/sharding-core/sharding-core-common/src/main/java/org/apache/shardingsphere/core/metadata/datasource/dialect/MariaDBDataSourceMetaData.java new file mode 100644 index 0000000000000000000000000000000000000000..d4b56c7349f91de5f1ceee239ee2cbc8489e2159 --- /dev/null +++ b/sharding-core/sharding-core-common/src/main/java/org/apache/shardingsphere/core/metadata/datasource/dialect/MariaDBDataSourceMetaData.java @@ -0,0 +1,55 @@ +/* + * 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.core.metadata.datasource.dialect; + +import com.google.common.base.Strings; +import lombok.Getter; +import org.apache.shardingsphere.core.metadata.datasource.UnrecognizedDatabaseURLException; +import org.apache.shardingsphere.spi.database.DataSourceMetaData; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Data source meta data for MariaDB. + * + * @author yanqiufang + */ +@Getter +public final class MariaDBDataSourceMetaData implements DataSourceMetaData { + + private static final int DEFAULT_PORT = 3306; + + private final String hostName; + + private final int port; + + private final String schemaName; + + private final Pattern pattern = Pattern.compile("jdbc:(mysql|mariadb)(:replication|:failover|:sequential|:aurora)?:(\\w*:)?//([\\w\\-\\.]+):?([0-9]*)/([\\w\\-]+);?\\S*", Pattern.CASE_INSENSITIVE); + + public MariaDBDataSourceMetaData(final String url) { + Matcher matcher = pattern.matcher(url); + if (!matcher.find()) { + throw new UnrecognizedDatabaseURLException(url, pattern.pattern()); + } + hostName = matcher.group(4); + port = Strings.isNullOrEmpty(matcher.group(5)) ? DEFAULT_PORT : Integer.valueOf(matcher.group(5)); + schemaName = matcher.group(6); + } +} diff --git a/sharding-core/sharding-core-common/src/main/java/org/apache/shardingsphere/core/spi/database/MariaDBDatabaseType.java b/sharding-core/sharding-core-common/src/main/java/org/apache/shardingsphere/core/spi/database/MariaDBDatabaseType.java new file mode 100644 index 0000000000000000000000000000000000000000..cb015f7a0c0c90884fde44a91d24c487bfe98481 --- /dev/null +++ b/sharding-core/sharding-core-common/src/main/java/org/apache/shardingsphere/core/spi/database/MariaDBDatabaseType.java @@ -0,0 +1,56 @@ +/* + * 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.core.spi.database; + +import org.apache.shardingsphere.core.database.DatabaseTypes; +import org.apache.shardingsphere.core.metadata.datasource.dialect.MariaDBDataSourceMetaData; +import org.apache.shardingsphere.spi.database.BranchDatabaseType; +import org.apache.shardingsphere.spi.database.DataSourceMetaData; +import org.apache.shardingsphere.spi.database.DatabaseType; + +import java.util.Collection; +import java.util.Collections; + +/** + * Database type of Mariadb. + * + * @author yanqiufang + */ +public final class MariaDBDatabaseType implements BranchDatabaseType { + + @Override + public String getName() { + return "MariaDB"; + } + + @Override + public Collection getJdbcUrlPrefixAlias() { + return Collections.singletonList("jdbc:mariadb:"); + } + + @Override + public DataSourceMetaData getDataSourceMetaData(final String url) { + return new MariaDBDataSourceMetaData(url); + } + + @Override + public DatabaseType getTrunkDatabaseType() { + return DatabaseTypes.getActualDatabaseType("MySQL"); + } + +} diff --git a/sharding-core/sharding-core-common/src/main/resources/META-INF/services/org.apache.shardingsphere.spi.database.DatabaseType b/sharding-core/sharding-core-common/src/main/resources/META-INF/services/org.apache.shardingsphere.spi.database.DatabaseType index 9457bcd4dc041e5869af7e08fbc70edc60069ec6..50ab74cf9b5c6e572358275ff65b5401dd17b983 100644 --- a/sharding-core/sharding-core-common/src/main/resources/META-INF/services/org.apache.shardingsphere.spi.database.DatabaseType +++ b/sharding-core/sharding-core-common/src/main/resources/META-INF/services/org.apache.shardingsphere.spi.database.DatabaseType @@ -16,6 +16,7 @@ # org.apache.shardingsphere.core.spi.database.MySQLDatabaseType +org.apache.shardingsphere.core.spi.database.MariaDBDatabaseType org.apache.shardingsphere.core.spi.database.PostgreSQLDatabaseType org.apache.shardingsphere.core.spi.database.OracleDatabaseType org.apache.shardingsphere.core.spi.database.SQLServerDatabaseType diff --git a/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/pom.xml b/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/pom.xml index 5dddef7dbeff1de79ed1890a1b2d40b34d53dc6c..43c40eb46ffd35802e2388190bda641532035063 100644 --- a/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/pom.xml +++ b/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/pom.xml @@ -75,6 +75,10 @@ mysql mysql-connector-java + + org.mariadb.jdbc + mariadb-java-client + org.postgresql postgresql diff --git a/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/main/java/org/apache/shardingsphere/transaction/xa/jta/connection/XAConnectionFactory.java b/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/main/java/org/apache/shardingsphere/transaction/xa/jta/connection/XAConnectionFactory.java index 0f3f17f7e29573e14f38f74b6de62155da81e182..73fedf322b5bc61e9d75efbf4801c752f9acb8b2 100644 --- a/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/main/java/org/apache/shardingsphere/transaction/xa/jta/connection/XAConnectionFactory.java +++ b/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/main/java/org/apache/shardingsphere/transaction/xa/jta/connection/XAConnectionFactory.java @@ -21,6 +21,7 @@ import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.apache.shardingsphere.spi.database.DatabaseType; import org.apache.shardingsphere.transaction.xa.jta.connection.dialect.H2XAConnectionWrapper; +import org.apache.shardingsphere.transaction.xa.jta.connection.dialect.MariaDBXAConnectionWrapper; import org.apache.shardingsphere.transaction.xa.jta.connection.dialect.MySQLXAConnectionWrapper; import org.apache.shardingsphere.transaction.xa.jta.connection.dialect.PostgreSQLXAConnectionWrapper; @@ -48,6 +49,8 @@ public final class XAConnectionFactory { switch (databaseType.getName()) { case "MySQL": return new MySQLXAConnectionWrapper().wrap(xaDataSource, connection); + case "MariaDB": + return new MariaDBXAConnectionWrapper().wrap(xaDataSource, connection); case "PostgreSQL": return new PostgreSQLXAConnectionWrapper().wrap(xaDataSource, connection); case "H2": diff --git a/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/main/java/org/apache/shardingsphere/transaction/xa/jta/connection/dialect/MariaDBXAConnectionWrapper.java b/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/main/java/org/apache/shardingsphere/transaction/xa/jta/connection/dialect/MariaDBXAConnectionWrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..ec1c620d706df28ae498f9ccf2b9261c6f62bac8 --- /dev/null +++ b/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/main/java/org/apache/shardingsphere/transaction/xa/jta/connection/dialect/MariaDBXAConnectionWrapper.java @@ -0,0 +1,44 @@ +/* + * 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.xa.jta.connection.dialect; + +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import org.apache.shardingsphere.transaction.xa.jta.connection.XAConnectionWrapper; +import org.mariadb.jdbc.MariaDbConnection; +import org.mariadb.jdbc.MariaXaConnection; + +import javax.sql.XAConnection; +import javax.sql.XADataSource; +import java.sql.Connection; + +/** + * XA connection wrapper for MariaDB. + * + * @author yanqiufang + */ +@RequiredArgsConstructor +public final class MariaDBXAConnectionWrapper implements XAConnectionWrapper { + + @SneakyThrows + @Override + public XAConnection wrap(final XADataSource xaDataSource, final Connection connection) { + MariaDbConnection physicalConnection = (MariaDbConnection) connection.unwrap(Class.forName("org.mariadb.jdbc.MariaDbConnection")); + return new MariaXaConnection(physicalConnection); + } +} diff --git a/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/main/java/org/apache/shardingsphere/transaction/xa/jta/datasource/properties/dialect/MariaDBXADataSourceDefinition.java b/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/main/java/org/apache/shardingsphere/transaction/xa/jta/datasource/properties/dialect/MariaDBXADataSourceDefinition.java new file mode 100644 index 0000000000000000000000000000000000000000..1d481c128238199e697e5478f59271e361181c72 --- /dev/null +++ b/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/main/java/org/apache/shardingsphere/transaction/xa/jta/datasource/properties/dialect/MariaDBXADataSourceDefinition.java @@ -0,0 +1,59 @@ +/* + * 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.xa.jta.datasource.properties.dialect; + +import com.google.common.base.Optional; +import org.apache.shardingsphere.core.config.DatabaseAccessConfiguration; +import org.apache.shardingsphere.core.metadata.datasource.dialect.MariaDBDataSourceMetaData; +import org.apache.shardingsphere.transaction.xa.jta.datasource.properties.XADataSourceDefinition; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Properties; + +/** + * XA data source definition for MariaDB. + * + * @author yanqiufang + */ +public final class MariaDBXADataSourceDefinition implements XADataSourceDefinition { + + @Override + public String getDatabaseType() { + return "MariaDB"; + } + + @Override + public Collection getXADriverClassName() { + return Collections.singletonList("org.mariadb.jdbc.MariaDbDataSource"); + } + + @Override + public Properties getXAProperties(final DatabaseAccessConfiguration databaseAccessConfiguration) { + Properties result = new Properties(); + MariaDBDataSourceMetaData dataSourceMetaData = new MariaDBDataSourceMetaData(databaseAccessConfiguration.getUrl()); + result.setProperty("user", databaseAccessConfiguration.getUsername()); + result.setProperty("password", Optional.fromNullable(databaseAccessConfiguration.getPassword()).or("")); + result.setProperty("url", databaseAccessConfiguration.getUrl()); + result.setProperty("ServerName", dataSourceMetaData.getHostName()); + result.setProperty("port", String.valueOf(dataSourceMetaData.getPort())); + result.setProperty("DatabaseName", dataSourceMetaData.getSchemaName()); + return result; + } +} diff --git a/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/main/resources/META-INF/services/org.apache.shardingsphere.transaction.xa.jta.datasource.properties.XADataSourceDefinition b/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/main/resources/META-INF/services/org.apache.shardingsphere.transaction.xa.jta.datasource.properties.XADataSourceDefinition index 5740e67a5d3aa28d356d60ce5ad8856976d8f914..fc31195d90028bf9f0ca87c4886ca07c46120522 100644 --- a/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/main/resources/META-INF/services/org.apache.shardingsphere.transaction.xa.jta.datasource.properties.XADataSourceDefinition +++ b/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/main/resources/META-INF/services/org.apache.shardingsphere.transaction.xa.jta.datasource.properties.XADataSourceDefinition @@ -16,6 +16,7 @@ # org.apache.shardingsphere.transaction.xa.jta.datasource.properties.dialect.MySQLXADataSourceDefinition +org.apache.shardingsphere.transaction.xa.jta.datasource.properties.dialect.MariaDBXADataSourceDefinition org.apache.shardingsphere.transaction.xa.jta.datasource.properties.dialect.PostgreSQLXADataSourceDefinition org.apache.shardingsphere.transaction.xa.jta.datasource.properties.dialect.OracleXADataSourceDefinition org.apache.shardingsphere.transaction.xa.jta.datasource.properties.dialect.SQLServerXADataSourceDefinition diff --git a/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/test/java/org/apache/shardingsphere/transaction/xa/fixture/DataSourceUtils.java b/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/test/java/org/apache/shardingsphere/transaction/xa/fixture/DataSourceUtils.java index 4c2cd4b471d0e3f29fff607ef3ebcf58c21254f1..891332333861f79a94dcb8a071f29c4a8fbd8a0c 100644 --- a/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/test/java/org/apache/shardingsphere/transaction/xa/fixture/DataSourceUtils.java +++ b/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/test/java/org/apache/shardingsphere/transaction/xa/fixture/DataSourceUtils.java @@ -127,6 +127,8 @@ public final class DataSourceUtils { switch (databaseType.getName()) { case "MySQL": return String.format("jdbc:mysql://localhost:3306/%s", databaseName); + case "MariaDB": + return String.format("jdbc:mariadb://localhost:3306/%s", databaseName); case "PostgreSQL": return String.format("jdbc:postgresql://localhost:5432/%s", databaseName); case "Oracle": diff --git a/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/test/java/org/apache/shardingsphere/transaction/xa/jta/connection/XAConnectionFactoryTest.java b/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/test/java/org/apache/shardingsphere/transaction/xa/jta/connection/XAConnectionFactoryTest.java index 14c20a597900b1c22d23b761f1e2e369cdc0ba0e..f339699826b03a341b837c6093fb6cfe67968132 100644 --- a/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/test/java/org/apache/shardingsphere/transaction/xa/jta/connection/XAConnectionFactoryTest.java +++ b/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/test/java/org/apache/shardingsphere/transaction/xa/jta/connection/XAConnectionFactoryTest.java @@ -21,6 +21,7 @@ import org.apache.shardingsphere.core.database.DatabaseTypes; import org.h2.jdbcx.JdbcXAConnection; import org.junit.Test; import org.junit.runner.RunWith; +import org.mariadb.jdbc.MariaXaConnection; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.postgresql.xa.PGXAConnection; @@ -45,7 +46,12 @@ public final class XAConnectionFactoryTest { public void assertCreateMySQLXAConnection() { XAConnectionFactory.createXAConnection(DatabaseTypes.getActualDatabaseType("MySQL"), xaDataSource, connection); } - + + @Test(expected = Exception.class) + public void assertCreateMariaDBXAConnection() { + assertThat(XAConnectionFactory.createXAConnection(DatabaseTypes.getActualDatabaseType("MariaDB"), xaDataSource, connection), instanceOf(MariaXaConnection.class)); + } + @Test public void assertCreatePostgreSQLXAConnection() { assertThat(XAConnectionFactory.createXAConnection(DatabaseTypes.getActualDatabaseType("PostgreSQL"), xaDataSource, connection), instanceOf(PGXAConnection.class)); diff --git a/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/test/java/org/apache/shardingsphere/transaction/xa/jta/connection/dialect/MariaDBXAConnectionWrapperTest.java b/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/test/java/org/apache/shardingsphere/transaction/xa/jta/connection/dialect/MariaDBXAConnectionWrapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..65f20bae50ec9c10aea3ce142125921e702d27a2 --- /dev/null +++ b/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/test/java/org/apache/shardingsphere/transaction/xa/jta/connection/dialect/MariaDBXAConnectionWrapperTest.java @@ -0,0 +1,66 @@ +/* + * 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.xa.jta.connection.dialect; + +import com.zaxxer.hikari.HikariDataSource; +import org.apache.shardingsphere.core.database.DatabaseTypes; +import org.apache.shardingsphere.transaction.xa.fixture.DataSourceUtils; +import org.apache.shardingsphere.transaction.xa.jta.datasource.XADataSourceFactory; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import javax.sql.DataSource; +import javax.sql.XAConnection; +import javax.sql.XADataSource; +import javax.transaction.xa.XAResource; +import java.sql.Connection; +import java.sql.SQLException; + +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public final class MariaDBXAConnectionWrapperTest { + + private XADataSource xaDataSource; + + @Mock + private Connection connection; + + @Before + @SuppressWarnings("unchecked") + public void setUp() throws SQLException, ClassNotFoundException { + Connection connection = (Connection) mock(Class.forName("org.mariadb.jdbc.MariaDbConnection")); + DataSource dataSource = DataSourceUtils.build(HikariDataSource.class, DatabaseTypes.getActualDatabaseType("MariaDB"), "ds1"); + xaDataSource = XADataSourceFactory.build(DatabaseTypes.getActualDatabaseType("MariaDB"), dataSource); + when(this.connection.unwrap((Class) any())).thenReturn(connection); + } + + @Test + public void assertCreateMariaDBConnection() throws SQLException { + XAConnection actual = new MariaDBXAConnectionWrapper().wrap(xaDataSource, connection); + assertThat(actual.getXAResource(), instanceOf(XAResource.class)); + assertThat(actual.getConnection(), instanceOf(Connection.class)); + } +}