From 6c8779719d4e51d0cce343f46ab33fd9b1790c06 Mon Sep 17 00:00:00 2001 From: Pramy Date: Mon, 28 Oct 2019 11:15:47 +0800 Subject: [PATCH] Implement MySQL time service (#3343) Change-Id: I791c1d3ff4c4cbf0f90464c7bb8bb9490dca4019 --- sharding-core/database-time-service/pom.xml | 46 ++++++++++ .../exception/TimeServiceInitException.java | 32 +++++++ .../route/time/mysql/MySQLTimeService.java | 84 +++++++++++++++++++ ....shardingsphere.core.route.spi.TimeService | 18 ++++ .../time/mysql/MySQLTimeServiceTest.java | 57 +++++++++++++ sharding-core/pom.xml | 1 + 6 files changed, 238 insertions(+) create mode 100644 sharding-core/database-time-service/pom.xml create mode 100644 sharding-core/database-time-service/src/main/java/org/apache/shardingsphere/route/time/exception/TimeServiceInitException.java create mode 100644 sharding-core/database-time-service/src/main/java/org/apache/shardingsphere/route/time/mysql/MySQLTimeService.java create mode 100644 sharding-core/database-time-service/src/main/resources/META-INF/services/org.apache.shardingsphere.core.route.spi.TimeService create mode 100644 sharding-core/database-time-service/src/test/java/org/apache/shardingsphere/route/time/mysql/MySQLTimeServiceTest.java diff --git a/sharding-core/database-time-service/pom.xml b/sharding-core/database-time-service/pom.xml new file mode 100644 index 0000000000..1bdd693250 --- /dev/null +++ b/sharding-core/database-time-service/pom.xml @@ -0,0 +1,46 @@ + + + + + + org.apache.shardingsphere + sharding-core + 4.0.0-RC3-SNAPSHOT + + 4.0.0 + database-time-service + ${project.artifactId} + + + + org.apache.shardingsphere + sharding-core-route + ${project.version} + + + com.zaxxer + HikariCP-java7 + + + mysql + mysql-connector-java + test + + + diff --git a/sharding-core/database-time-service/src/main/java/org/apache/shardingsphere/route/time/exception/TimeServiceInitException.java b/sharding-core/database-time-service/src/main/java/org/apache/shardingsphere/route/time/exception/TimeServiceInitException.java new file mode 100644 index 0000000000..7be1f93bd8 --- /dev/null +++ b/sharding-core/database-time-service/src/main/java/org/apache/shardingsphere/route/time/exception/TimeServiceInitException.java @@ -0,0 +1,32 @@ +/* + * 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.route.time.exception; + +/** + * TimeService init exception. + * + * @author chenchuangliu + */ +public class TimeServiceInitException extends RuntimeException { + + private static final long serialVersionUID = -834638295454826244L; + + public TimeServiceInitException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/sharding-core/database-time-service/src/main/java/org/apache/shardingsphere/route/time/mysql/MySQLTimeService.java b/sharding-core/database-time-service/src/main/java/org/apache/shardingsphere/route/time/mysql/MySQLTimeService.java new file mode 100644 index 0000000000..70546608b0 --- /dev/null +++ b/sharding-core/database-time-service/src/main/java/org/apache/shardingsphere/route/time/mysql/MySQLTimeService.java @@ -0,0 +1,84 @@ +/* + * 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.route.time.mysql; + +import org.apache.shardingsphere.core.route.spi.TimeService; +import org.apache.shardingsphere.route.time.exception.TimeServiceInitException; + +import javax.sql.DataSource; +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Date; +import java.util.Properties; + +/** + * MySQL time service. + * Need to create a mysql-time-service.properties file under the classpath. + * + * @author chenchuangliu + */ +public final class MySQLTimeService implements TimeService { + + private static DataSource dataSource; + + static { + init(); + } + + private static void init() { + try { + Properties properties = new Properties(); + properties.load(MySQLTimeService.class.getResourceAsStream("/mysql-time-service.properties")); + if (properties.isEmpty()) { + return; + } + String dataSourceType = (String) properties.remove("dataSourceType"); + Class dataSourceClass = Class.forName(dataSourceType); + DataSource dataSource = (DataSource) dataSourceClass.newInstance(); + for (String each : properties.stringPropertyNames()) { + PropertyDescriptor propertyDescriptor = new PropertyDescriptor(each, dataSourceClass); + Method writeMethod = propertyDescriptor.getWriteMethod(); + writeMethod.invoke(dataSource, properties.getProperty(each)); + } + MySQLTimeService.dataSource = dataSource; + } catch (final NullPointerException | IOException | ClassNotFoundException | InstantiationException | IllegalAccessException | InvocationTargetException | IntrospectionException e) { + throw new TimeServiceInitException("please check your mysql-time-service.properties", e); + } + } + + @Override + public Date getTime() { + if (null != dataSource) { + try (Connection connection = dataSource.getConnection(); + PreparedStatement preparedStatement = connection.prepareStatement("select now()"); + ResultSet resultSet = preparedStatement.executeQuery()) { + resultSet.next(); + return (Date) resultSet.getObject(1); + } catch (final SQLException ignore) { + } + } + return new Date(); + } +} diff --git a/sharding-core/database-time-service/src/main/resources/META-INF/services/org.apache.shardingsphere.core.route.spi.TimeService b/sharding-core/database-time-service/src/main/resources/META-INF/services/org.apache.shardingsphere.core.route.spi.TimeService new file mode 100644 index 0000000000..82d289f1b9 --- /dev/null +++ b/sharding-core/database-time-service/src/main/resources/META-INF/services/org.apache.shardingsphere.core.route.spi.TimeService @@ -0,0 +1,18 @@ +# +# 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. +# + +org.apache.shardingsphere.route.time.mysql.MySQLTimeService diff --git a/sharding-core/database-time-service/src/test/java/org/apache/shardingsphere/route/time/mysql/MySQLTimeServiceTest.java b/sharding-core/database-time-service/src/test/java/org/apache/shardingsphere/route/time/mysql/MySQLTimeServiceTest.java new file mode 100644 index 0000000000..b3c32792dd --- /dev/null +++ b/sharding-core/database-time-service/src/test/java/org/apache/shardingsphere/route/time/mysql/MySQLTimeServiceTest.java @@ -0,0 +1,57 @@ +/* + * 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.route.time.mysql; + +import lombok.SneakyThrows; +import org.junit.Assert; +import org.junit.Test; + +import javax.sql.DataSource; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.Properties; + +public final class MySQLTimeServiceTest { + + private final File file = new File(MySQLTimeServiceTest.class.getResource("/").getPath() + "mysql-time-service.properties"); + + @Test + public void assertInitDataSource() throws IOException { + FileOutputStream stream = new FileOutputStream(file); + Properties properties = new Properties(); + properties.put("dataSourceType", "com.zaxxer.hikari.HikariDataSource"); + properties.put("jdbcUrl", "jdbc:mysql://localhost:3306/test"); + properties.put("username", "root"); + properties.put("password", "root"); + properties.put("driverClassName", "com.mysql.jdbc.Driver"); + properties.store(stream, null); + stream.close(); + MySQLTimeService service = new MySQLTimeService(); + Assert.assertNotNull(getDataSource(service)); + Assert.assertTrue(file.delete()); + } + + @SneakyThrows + private DataSource getDataSource(final MySQLTimeService service) { + Field field = service.getClass().getDeclaredField("dataSource"); + field.setAccessible(true); + return (DataSource) field.get(null); + } +} diff --git a/sharding-core/pom.xml b/sharding-core/pom.xml index d4e812c6b7..022c4fd38c 100644 --- a/sharding-core/pom.xml +++ b/sharding-core/pom.xml @@ -33,6 +33,7 @@ sharding-core-parse sharding-core-preprocessor sharding-core-route + database-time-service sharding-core-rewrite sharding-core-execute sharding-core-merge -- GitLab