From 0bc2804049deaeea493e3fe98cf0cb364db50c89 Mon Sep 17 00:00:00 2001 From: xiaoyu <549477611@qq.com> Date: Wed, 20 May 2020 19:05:33 +0800 Subject: [PATCH] Optimize user configuration of datasource. (#5709) * add common datasource config . * merged master into. --- .../boot/datasource/DataSourceMapSetter.java | 19 ++++- .../spring/boot/util/PropertyUtil.java | 3 +- .../datasource/DataSourceMapSetterTest.java | 79 +++++++++++++++++++ 3 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-spring-boot-util/src/test/java/org/apache/shardingsphere/spring/boot/datasource/DataSourceMapSetterTest.java diff --git a/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-spring-boot-util/src/main/java/org/apache/shardingsphere/spring/boot/datasource/DataSourceMapSetter.java b/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-spring-boot-util/src/main/java/org/apache/shardingsphere/spring/boot/datasource/DataSourceMapSetter.java index 66da3dd1d8..0259025750 100644 --- a/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-spring-boot-util/src/main/java/org/apache/shardingsphere/spring/boot/datasource/DataSourceMapSetter.java +++ b/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-spring-boot-util/src/main/java/org/apache/shardingsphere/spring/boot/datasource/DataSourceMapSetter.java @@ -44,6 +44,8 @@ public final class DataSourceMapSetter { private static final String PREFIX = "spring.shardingsphere.datasource."; + private static final String COMMON_PREFIX = "spring.shardingsphere.datasource.common."; + private static final String DATA_SOURCE_NAME = "name"; private static final String DATA_SOURCE_NAMES = "names"; @@ -60,9 +62,10 @@ public final class DataSourceMapSetter { */ public static Map getDataSourceMap(final Environment environment) { Map result = new LinkedHashMap<>(); + Map dataSourceCommonProps = PropertyUtil.handle(environment, COMMON_PREFIX, Map.class); for (String each : getDataSourceNames(environment, PREFIX)) { try { - result.put(each, getDataSource(environment, PREFIX, each)); + result.put(each, getDataSource(environment, PREFIX, each, dataSourceCommonProps)); } catch (final ReflectiveOperationException ex) { throw new ShardingSphereException("Can't find data source type.", ex); } catch (final NamingException ex) { @@ -83,8 +86,9 @@ public final class DataSourceMapSetter { } @SuppressWarnings("unchecked") - private static DataSource getDataSource(final Environment environment, final String prefix, final String dataSourceName) throws ReflectiveOperationException, NamingException { - Map dataSourceProps = PropertyUtil.handle(environment, prefix + dataSourceName.trim(), Map.class); + private static DataSource getDataSource(final Environment environment, final String prefix, final String dataSourceName, + final Map dataSourceCommonProps) throws ReflectiveOperationException, NamingException { + Map dataSourceProps = mergedDataSourceProps(PropertyUtil.handle(environment, prefix + dataSourceName.trim(), Map.class), dataSourceCommonProps); Preconditions.checkState(!dataSourceProps.isEmpty(), String.format("Wrong datasource [%s] properties.", dataSourceName)); if (dataSourceProps.containsKey(JNDI_NAME)) { return getJNDIDataSource(dataSourceProps.get(JNDI_NAME).toString()); @@ -95,6 +99,15 @@ public final class DataSourceMapSetter { return result; } + private static Map mergedDataSourceProps(final Map dataSourceProps, final Map dataSourceCommonProps) { + if (!dataSourceCommonProps.isEmpty()) { + dataSourceCommonProps.putAll(dataSourceProps); + return dataSourceCommonProps; + } else { + return dataSourceProps; + } + } + private static DataSource getJNDIDataSource(final String jndiName) throws NamingException { JndiObjectFactoryBean bean = new JndiObjectFactoryBean(); bean.setResourceRef(true); diff --git a/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-spring-boot-util/src/main/java/org/apache/shardingsphere/spring/boot/util/PropertyUtil.java b/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-spring-boot-util/src/main/java/org/apache/shardingsphere/spring/boot/util/PropertyUtil.java index 0dfdb045c4..6da3ced966 100644 --- a/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-spring-boot-util/src/main/java/org/apache/shardingsphere/spring/boot/util/PropertyUtil.java +++ b/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-spring-boot-util/src/main/java/org/apache/shardingsphere/spring/boot/util/PropertyUtil.java @@ -26,7 +26,6 @@ import org.springframework.core.env.PropertyResolver; import java.lang.reflect.Constructor; import java.lang.reflect.Method; -import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; @@ -102,7 +101,7 @@ public final class PropertyUtil { propertiesWithPlaceholderResolved.put(key, value); } } - return Collections.unmodifiableMap(propertiesWithPlaceholderResolved); + return propertiesWithPlaceholderResolved; } @SneakyThrows(ReflectiveOperationException.class) diff --git a/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-spring-boot-util/src/test/java/org/apache/shardingsphere/spring/boot/datasource/DataSourceMapSetterTest.java b/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-spring-boot-util/src/test/java/org/apache/shardingsphere/spring/boot/datasource/DataSourceMapSetterTest.java new file mode 100644 index 0000000000..eb8c105184 --- /dev/null +++ b/shardingsphere-jdbc/shardingsphere-jdbc-spring/shardingsphere-jdbc-spring-boot-util/src/test/java/org/apache/shardingsphere/spring/boot/datasource/DataSourceMapSetterTest.java @@ -0,0 +1,79 @@ +/* + * 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.spring.boot.datasource; + +import lombok.SneakyThrows; +import org.junit.Test; +import org.springframework.core.env.StandardEnvironment; +import org.springframework.mock.env.MockEnvironment; + +import javax.sql.DataSource; +import java.util.Map; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public final class DataSourceMapSetterTest { + + @SneakyThrows + @Test + public void assetMergedAll() { + MockEnvironment mockEnvironment = new MockEnvironment(); + mockEnvironment.setProperty("spring.shardingsphere.datasource.names", "ds0,ds1"); + mockEnvironment.setProperty("spring.shardingsphere.datasource.common.type", "org.apache.commons.dbcp2.BasicDataSource"); + mockEnvironment.setProperty("spring.shardingsphere.datasource.common.driver-class-name", "org.h2.Driver"); + mockEnvironment.setProperty("spring.shardingsphere.datasource.common.max-total", "100"); + mockEnvironment.setProperty("spring.shardingsphere.datasource.common.username", "sa"); + mockEnvironment.setProperty("spring.shardingsphere.datasource.common.password", ""); + mockEnvironment.setProperty("spring.shardingsphere.datasource.ds0.url", "jdbc:h2:mem:ds;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MYSQL"); + mockEnvironment.setProperty("spring.shardingsphere.datasource.ds1.url", "jdbc:h2:mem:ds;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MYSQL"); + StandardEnvironment standardEnvironment = new StandardEnvironment(); + standardEnvironment.merge(mockEnvironment); + Map dataSourceMap = DataSourceMapSetter.getDataSourceMap(standardEnvironment); + assertThat(dataSourceMap.size(), is(2)); + assertThat(dataSourceMap.get("ds0").getConnection().getMetaData().getURL(), is("jdbc:h2:mem:ds")); + assertThat(dataSourceMap.get("ds1").getConnection().getMetaData().getURL(), is("jdbc:h2:mem:ds")); + } + + @SneakyThrows + @Test + public void assetMergedReplaceAndAdd() { + MockEnvironment mockEnvironment = new MockEnvironment(); + mockEnvironment.setProperty("spring.shardingsphere.datasource.names", "ds0,ds1"); + mockEnvironment.setProperty("spring.shardingsphere.datasource.common.type", "org.apache.commons.dbcp2.BasicDataSource"); + mockEnvironment.setProperty("spring.shardingsphere.datasource.common.driver-class-name", "org.h2.Driver"); + mockEnvironment.setProperty("spring.shardingsphere.datasource.common.max-total", "100"); + mockEnvironment.setProperty("spring.shardingsphere.datasource.common.username", "Asa"); + mockEnvironment.setProperty("spring.shardingsphere.datasource.common.password", "123"); + mockEnvironment.setProperty("spring.shardingsphere.datasource.ds0.url", "jdbc:h2:mem:ds;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MYSQL"); + mockEnvironment.setProperty("spring.shardingsphere.datasource.ds0.username", "sa"); + mockEnvironment.setProperty("spring.shardingsphere.datasource.ds0.max-total", "50"); + mockEnvironment.setProperty("spring.shardingsphere.datasource.ds0.password", ""); + mockEnvironment.setProperty("spring.shardingsphere.datasource.ds1.url", "jdbc:h2:mem:ds;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MYSQL"); + mockEnvironment.setProperty("spring.shardingsphere.datasource.ds1.username", "sa"); + mockEnvironment.setProperty("spring.shardingsphere.datasource.ds1.max-total", "150"); + mockEnvironment.setProperty("spring.shardingsphere.datasource.ds1.password", ""); + StandardEnvironment standardEnvironment = new StandardEnvironment(); + standardEnvironment.merge(mockEnvironment); + Map dataSourceMap = DataSourceMapSetter.getDataSourceMap(standardEnvironment); + assertThat(dataSourceMap.size(), is(2)); + assertThat(dataSourceMap.get("ds0").getConnection().getMetaData().getUserName(), is("SA")); + assertThat(dataSourceMap.get("ds1").getConnection().getMetaData().getUserName(), is("SA")); + } +} + -- GitLab