This is an automated email from the ASF dual-hosted git repository.
panjuan 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 82b5f7c For #11100, change 'add reource' syntax and allow custom
properties for connection pool. (#11185)
82b5f7c is described below
commit 82b5f7cfcb9538197f2c59c935e75f65513738ca
Author: Raigor <[email protected]>
AuthorDate: Thu Jul 8 16:05:03 2021 +0800
For #11100, change 'add reource' syntax and allow custom properties for
connection pool. (#11185)
* For #11100, add URL item to `add resoutce` syntax.
* delete unused parameter `databaseType`
* optimize setter logic for connection pool and jdbc param.
* add default value for 'useSSL' and 'serverTimezone', add test case.
* fix ci.
* fix checktStyle.
* allow SIMPLE or URL configuration for `Add Resource`.
* fix style and add test cases.
* fix merge conflicts.
* replace 'indexOf' to 'URI.getQuery' to find url properties.
* replace 'URI.getQuery' to 'regular' to find jdbc url properties.
* optimize parser & add tast cases.
---
.../src/main/antlr4/imports/Keyword.g4 | 4 +
.../src/main/antlr4/imports/RDLStatement.g4 | 22 +++-
.../resource/ResourceDistSQLStatementVisitor.java | 26 +++--
.../api/DistSQLStatementParserEngineTest.java | 93 ++++++++++++++---
.../distsql/parser/segment/DataSourceSegment.java | 2 +
.../config/datasource/DataSourceConfiguration.java | 19 +++-
.../config/datasource/DataSourceParameter.java | 4 +
.../infra/config/DataSourceConfigurationTest.java | 24 +++++
.../jdbc/connection/ConnectionUrlParser.java | 86 +++++++++++++++
.../decorator/HikariJDBCParameterDecorator.java | 38 ++++---
.../jdbc/connection/ConnectionUrlParserTest.java | 115 +++++++++++++++++++++
.../HikariJDBCParameterDecoratorTest.java | 26 +++++
.../resource/AddResourceBackendHandlerTest.java | 2 +-
.../config/util/DataSourceParameterConverter.java | 7 ++
.../proxy/config/yaml/YamlDataSourceParameter.java | 4 +
.../converter/AddResourcesStatementConverter.java | 4 +
.../util/DataSourceParameterConverterTest.java | 17 ++-
.../AddResourcesStatementConverterTest.java | 8 +-
.../asserts/segment/distsql/DataSourceAssert.java | 2 +
.../segment/impl/distsql/ExpectedDataSource.java | 3 +
.../src/main/resources/case/rdl/create.xml | 19 +++-
.../main/resources/sql/supported/rdl/create.xml | 9 +-
22 files changed, 480 insertions(+), 54 deletions(-)
diff --git
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/imports/Keyword.g4
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/imports/Keyword.g4
index f009912..fabe60b 100644
---
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/imports/Keyword.g4
+++
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/imports/Keyword.g4
@@ -47,6 +47,10 @@ FROM
: F R O M
;
+URL
+ : U R L
+ ;
+
HOST
: H O S T
;
diff --git
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/imports/RDLStatement.g4
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/imports/RDLStatement.g4
index 28f607f..e71b952 100644
---
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/imports/RDLStatement.g4
+++
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/antlr4/imports/RDLStatement.g4
@@ -28,13 +28,21 @@ dropResource
;
dataSource
- : dataSourceName LP HOST EQ hostName COMMA PORT EQ port COMMA DB EQ dbName
COMMA USER EQ user (COMMA PASSWORD EQ password)? (COMMA PROPERTIES LP
connectionProperties? RP)? RP
+ : dataSourceName LP (simpleSource | urlSource) COMMA USER EQ user (COMMA
PASSWORD EQ password)? (COMMA PROPERTIES LP poolProperties? RP)? RP
;
dataSourceName
: IDENTIFIER
;
+simpleSource
+ : HOST EQ hostName COMMA PORT EQ port COMMA DB EQ dbName
+ ;
+
+urlSource
+ : URL EQ url
+ ;
+
hostName
: IDENTIFIER | ip
;
@@ -51,6 +59,10 @@ dbName
: IDENTIFIER
;
+url
+ : (IDENTIFIER | STRING)
+ ;
+
user
: IDENTIFIER | NUMBER
;
@@ -59,10 +71,10 @@ password
: IDENTIFIER | INT | STRING
;
-connectionProperties
- : connectionProperty (COMMA connectionProperty)*
+poolProperties
+ : poolProperty (COMMA poolProperty)*
;
-connectionProperty
- : key=IDENTIFIER EQ value=IDENTIFIER
+poolProperty
+ : key=(IDENTIFIER | STRING) EQ value=(INT | IDENTIFIER | STRING)
;
diff --git
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/java/org/apache/shardingsphere/distsql/parser/core/resource/ResourceDistSQLStatementVisitor.java
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/java/org/apache/shardingsphere/distsql/parser/core/resource/ResourceDistSQLStatementVisitor.java
index 60f54e1..a1db4a5 100644
---
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/java/org/apache/shardingsphere/distsql/parser/core/resource/ResourceDistSQLStatementVisitor.java
+++
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/main/java/org/apache/shardingsphere/distsql/parser/core/resource/ResourceDistSQLStatementVisitor.java
@@ -24,8 +24,8 @@ import
org.apache.shardingsphere.distsql.parser.autogen.ResourceStatementParser.
import
org.apache.shardingsphere.distsql.parser.autogen.ResourceStatementParser.DropResourceContext;
import
org.apache.shardingsphere.distsql.parser.autogen.ResourceStatementParser.SchemaNameContext;
import
org.apache.shardingsphere.distsql.parser.autogen.ResourceStatementParser.ShowResourcesContext;
-import
org.apache.shardingsphere.distsql.parser.autogen.ResourceStatementParser.ConnectionPropertiesContext;
-import
org.apache.shardingsphere.distsql.parser.autogen.ResourceStatementParser.ConnectionPropertyContext;
+import
org.apache.shardingsphere.distsql.parser.autogen.ResourceStatementParser.PoolPropertiesContext;
+import
org.apache.shardingsphere.distsql.parser.autogen.ResourceStatementParser.PoolPropertyContext;
import org.apache.shardingsphere.distsql.parser.segment.DataSourceSegment;
import
org.apache.shardingsphere.distsql.parser.statement.rdl.create.AddResourceStatement;
import
org.apache.shardingsphere.distsql.parser.statement.rdl.drop.DropResourceStatement;
@@ -50,14 +50,26 @@ public final class ResourceDistSQLStatementVisitor extends
ResourceStatementBase
@Override
public ASTNode visitDataSource(final DataSourceContext ctx) {
- return new DataSourceSegment(
- ctx.dataSourceName().getText(), ctx.hostName().getText(),
ctx.port().getText(), ctx.dbName().getText(), ctx.user().getText(), null ==
ctx.password() ? "" : ctx.password().getText(),
- null == ctx.connectionProperties() ? new Properties() :
getConnectionProperties(ctx.connectionProperties()));
+ String url = null;
+ String hostName = null;
+ String port = null;
+ String dbName = null;
+ if (null != ctx.urlSource()) {
+ url = new
IdentifierValue(ctx.urlSource().url().getText()).getValue();
+ }
+ if (null != ctx.simpleSource()) {
+ hostName = ctx.simpleSource().hostName().getText();
+ port = ctx.simpleSource().port().getText();
+ dbName = ctx.simpleSource().dbName().getText();
+ }
+ return new DataSourceSegment(ctx.dataSourceName().getText(), url,
hostName, port, dbName,
+ ctx.user().getText(), null == ctx.password() ? "" :
ctx.password().getText(),
+ null == ctx.poolProperties() ? new Properties() :
getPoolProperties(ctx.poolProperties()));
}
- private Properties getConnectionProperties(final
ConnectionPropertiesContext ctx) {
+ private Properties getPoolProperties(final PoolPropertiesContext ctx) {
Properties result = new Properties();
- for (ConnectionPropertyContext each : ctx.connectionProperty()) {
+ for (PoolPropertyContext each : ctx.poolProperty()) {
result.setProperty(new
IdentifierValue(each.key.getText()).getValue(), new
IdentifierValue(each.value.getText()).getValue());
}
return result;
diff --git
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/test/java/org/apache/shardingsphere/distsql/parser/api/DistSQLStatementParserEngineTest.java
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/test/java/org/apache/shardingsphere/distsql/parser/api/DistSQLStatementParserEngineTest.java
index 41d51dc..3774cc7 100644
---
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/test/java/org/apache/shardingsphere/distsql/parser/api/DistSQLStatementParserEngineTest.java
+++
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-engine/src/test/java/org/apache/shardingsphere/distsql/parser/api/DistSQLStatementParserEngineTest.java
@@ -41,10 +41,19 @@ public final class DistSQLStatementParserEngineTest {
private static final String ADD_RESOURCE_MULTIPLE = "ADD RESOURCE
ds_0(HOST=127.0.0.1,PORT=3306,DB=test0,USER=ROOT,PASSWORD=123456),"
+
"ds_1(HOST=127.0.0.1,PORT=3306,DB=test1,USER=ROOT,PASSWORD=123456);";
- private static final String ADD_RESOURCE_SINGLE_WITH_EMPTY_PROPERTIES =
"ADD RESOURCE ds_0(HOST=127.0.0.1,PORT=3306,DB=test0,USER=ROOT,PROPERTIES());";
+ private static final String ADD_RESOURCE_SINGLE_WITH_PROPERTIES = "ADD
RESOURCE
ds_0(HOST=127.0.0.1,PORT=3306,DB=test0,USER=ROOT,PASSWORD=123456,PROPERTIES(\"maxPoolSize\"=30));";
- private static final String ADD_RESOURCE_SINGLE_WITH_PROPERTIES = "ADD
RESOURCE
ds_0(HOST=127.0.0.1,PORT=3306,DB=test0,USER=ROOT,PASSWORD=123456,PROPERTIES("
- + "\"useSSL\"=\"false\",\"serverTimezone\"=\"UTC\"));";
+ private static final String ADD_RESOURCE_SINGLE_WITHOUT_PASSWORD_BY_URL =
"ADD RESOURCE ds_0(URL=\"jdbc:mysql://127.0.0.1:3306/test0\",USER=ROOT);";
+
+ private static final String ADD_RESOURCE_SINGLE_WITH_PASSWORD_BY_URL =
"ADD RESOURCE
ds_0(URL=\"jdbc:mysql://127.0.0.1:3306/test0\",USER=ROOT,PASSWORD=123456);";
+
+ private static final String ADD_RESOURCE_MULTIPLE_BY_URL = "ADD RESOURCE
ds_0(URL=\"jdbc:mysql://127.0.0.1:3306/test0\",USER=ROOT,PASSWORD=123456),"
+ +
"ds_1(URL=\"jdbc:mysql://127.0.0.1:3306/test1\",USER=ROOT,PASSWORD=123456);";
+
+ private static final String
ADD_RESOURCE_SINGLE_WITH_EMPTY_PROPERTIES_BY_URL = "ADD RESOURCE
ds_0(URL=\"jdbc:mysql://127.0.0.1:3306/test0\",USER=ROOT,PROPERTIES());";
+
+ private static final String ADD_RESOURCE_SINGLE_WITH_PROPERTIES_BY_URL =
"ADD RESOURCE
ds_0(URL=\"jdbc:mysql://127.0.0.1:3306/test0\",USER=ROOT,PASSWORD=123456,PROPERTIES("
+ + "\"maxPoolSize\"=30));";
private static final String DROP_RESOURCE = "DROP RESOURCE ds_0,ds_1";
@@ -100,6 +109,63 @@ public final class DistSQLStatementParserEngineTest {
}
@Test
+ public void assertParseAddSingleResourceWithProperties() {
+ SQLStatement sqlStatement =
engine.parse(ADD_RESOURCE_SINGLE_WITH_PROPERTIES);
+ assertTrue(sqlStatement instanceof AddResourceStatement);
+ assertThat(((AddResourceStatement)
sqlStatement).getDataSources().size(), is(1));
+ DataSourceSegment dataSourceSegment = ((AddResourceStatement)
sqlStatement).getDataSources().iterator().next();
+ assertThat(dataSourceSegment.getName(), is("ds_0"));
+ assertThat(dataSourceSegment.getHostName(), is("127.0.0.1"));
+ assertThat(dataSourceSegment.getPort(), is("3306"));
+ assertThat(dataSourceSegment.getDb(), is("test0"));
+ assertThat(dataSourceSegment.getUser(), is("ROOT"));
+ assertThat(dataSourceSegment.getPassword(), is("123456"));
+ assertThat(dataSourceSegment.getProperties().size(), is(1));
+
assertThat(dataSourceSegment.getProperties().getProperty("maxPoolSize"),
is("30"));
+ }
+
+ @Test
+ public void assertParseAddSingleResourceWithoutPasswordByUrl() {
+ SQLStatement sqlStatement =
engine.parse(ADD_RESOURCE_SINGLE_WITHOUT_PASSWORD_BY_URL);
+ assertTrue(sqlStatement instanceof AddResourceStatement);
+ assertThat(((AddResourceStatement)
sqlStatement).getDataSources().size(), is(1));
+ DataSourceSegment dataSourceSegment = ((AddResourceStatement)
sqlStatement).getDataSources().iterator().next();
+ assertThat(dataSourceSegment.getName(), is("ds_0"));
+ assertThat(dataSourceSegment.getUrl(),
is("jdbc:mysql://127.0.0.1:3306/test0"));
+ assertThat(dataSourceSegment.getUser(), is("ROOT"));
+ }
+
+ @Test
+ public void assertParseAddSingleResourceWithPasswordByUrl() {
+ SQLStatement sqlStatement =
engine.parse(ADD_RESOURCE_SINGLE_WITH_PASSWORD_BY_URL);
+ assertTrue(sqlStatement instanceof AddResourceStatement);
+ assertThat(((AddResourceStatement)
sqlStatement).getDataSources().size(), is(1));
+ DataSourceSegment dataSourceSegment = ((AddResourceStatement)
sqlStatement).getDataSources().iterator().next();
+ assertThat(dataSourceSegment.getName(), is("ds_0"));
+ assertThat(dataSourceSegment.getUrl(),
is("jdbc:mysql://127.0.0.1:3306/test0"));
+ assertThat(dataSourceSegment.getUser(), is("ROOT"));
+ assertThat(dataSourceSegment.getPassword(), is("123456"));
+ }
+
+ @Test
+ public void assertParseAddMultipleResourcesByUrl() {
+ SQLStatement sqlStatement = engine.parse(ADD_RESOURCE_MULTIPLE_BY_URL);
+ assertTrue(sqlStatement instanceof AddResourceStatement);
+ assertThat(((AddResourceStatement)
sqlStatement).getDataSources().size(), is(2));
+ List<DataSourceSegment> dataSourceSegments = new
ArrayList<>(((AddResourceStatement) sqlStatement).getDataSources());
+ DataSourceSegment dataSourceSegment = dataSourceSegments.get(0);
+ assertThat(dataSourceSegment.getName(), is("ds_0"));
+ assertThat(dataSourceSegment.getUrl(),
is("jdbc:mysql://127.0.0.1:3306/test0"));
+ assertThat(dataSourceSegment.getUser(), is("ROOT"));
+ assertThat(dataSourceSegment.getPassword(), is("123456"));
+ dataSourceSegment = dataSourceSegments.get(1);
+ assertThat(dataSourceSegment.getName(), is("ds_1"));
+ assertThat(dataSourceSegment.getUrl(),
is("jdbc:mysql://127.0.0.1:3306/test1"));
+ assertThat(dataSourceSegment.getUser(), is("ROOT"));
+ assertThat(dataSourceSegment.getPassword(), is("123456"));
+ }
+
+ @Test
public void assertParseDropResource() {
SQLStatement sqlStatement = engine.parse(DROP_RESOURCE);
assertTrue(sqlStatement instanceof DropResourceStatement);
@@ -108,33 +174,28 @@ public final class DistSQLStatementParserEngineTest {
}
@Test
- public void assertParseAddSingleResourceWithEmptyProperties() {
- SQLStatement sqlStatement =
engine.parse(ADD_RESOURCE_SINGLE_WITH_EMPTY_PROPERTIES);
+ public void assertParseAddSingleResourceWithEmptyPropertiesByUrl() {
+ SQLStatement sqlStatement =
engine.parse(ADD_RESOURCE_SINGLE_WITH_EMPTY_PROPERTIES_BY_URL);
assertTrue(sqlStatement instanceof AddResourceStatement);
assertThat(((AddResourceStatement)
sqlStatement).getDataSources().size(), is(1));
DataSourceSegment dataSourceSegment = ((AddResourceStatement)
sqlStatement).getDataSources().iterator().next();
assertThat(dataSourceSegment.getName(), is("ds_0"));
- assertThat(dataSourceSegment.getHostName(), is("127.0.0.1"));
- assertThat(dataSourceSegment.getPort(), is("3306"));
- assertThat(dataSourceSegment.getDb(), is("test0"));
+ assertThat(dataSourceSegment.getUrl(),
is("jdbc:mysql://127.0.0.1:3306/test0"));
assertThat(dataSourceSegment.getUser(), is("ROOT"));
assertThat(dataSourceSegment.getProperties().size(), is(0));
}
@Test
- public void assertParseAddSingleResourceWithProperties() {
- SQLStatement sqlStatement =
engine.parse(ADD_RESOURCE_SINGLE_WITH_PROPERTIES);
+ public void assertParseAddSingleResourceWithPropertiesByUrl() {
+ SQLStatement sqlStatement =
engine.parse(ADD_RESOURCE_SINGLE_WITH_PROPERTIES_BY_URL);
assertTrue(sqlStatement instanceof AddResourceStatement);
assertThat(((AddResourceStatement)
sqlStatement).getDataSources().size(), is(1));
DataSourceSegment dataSourceSegment = ((AddResourceStatement)
sqlStatement).getDataSources().iterator().next();
assertThat(dataSourceSegment.getName(), is("ds_0"));
- assertThat(dataSourceSegment.getHostName(), is("127.0.0.1"));
- assertThat(dataSourceSegment.getPort(), is("3306"));
- assertThat(dataSourceSegment.getDb(), is("test0"));
+ assertThat(dataSourceSegment.getUrl(),
is("jdbc:mysql://127.0.0.1:3306/test0"));
assertThat(dataSourceSegment.getUser(), is("ROOT"));
assertThat(dataSourceSegment.getPassword(), is("123456"));
- assertThat(dataSourceSegment.getProperties().size(), is(2));
- assertThat(dataSourceSegment.getProperties().getProperty("useSSL"),
is("false"));
-
assertThat(dataSourceSegment.getProperties().getProperty("serverTimezone"),
is("UTC"));
+ assertThat(dataSourceSegment.getProperties().size(), is(1));
+
assertThat(dataSourceSegment.getProperties().getProperty("maxPoolSize"),
is("30"));
}
}
diff --git
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-statement/src/main/java/org/apache/shardingsphere/distsql/parser/segment/DataSourceSegment.java
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-statement/src/main/java/org/apache/shardingsphere/distsql/parser/segment/DataSourceSegment.java
index 6166c49..ae80450 100644
---
a/shardingsphere-distsql-parser/shardingsphere-distsql-parser-statement/src/main/java/org/apache/shardingsphere/distsql/parser/segment/DataSourceSegment.java
+++
b/shardingsphere-distsql-parser/shardingsphere-distsql-parser-statement/src/main/java/org/apache/shardingsphere/distsql/parser/segment/DataSourceSegment.java
@@ -32,6 +32,8 @@ public final class DataSourceSegment implements ASTNode {
private final String name;
+ private final String url;
+
private final String hostName;
private final String port;
diff --git
a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/config/datasource/DataSourceConfiguration.java
b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/config/datasource/DataSourceConfiguration.java
index e89c479..64899b3 100644
---
a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/config/datasource/DataSourceConfiguration.java
+++
b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/config/datasource/DataSourceConfiguration.java
@@ -28,6 +28,7 @@ import
org.apache.shardingsphere.infra.config.exception.ShardingSphereConfigurat
import org.apache.shardingsphere.infra.spi.ShardingSphereServiceLoader;
import javax.sql.DataSource;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
@@ -116,8 +117,7 @@ public final class DataSourceConfiguration {
try {
Optional<Method> setterMethod = findSetterMethod(methods,
entry.getKey());
if (setterMethod.isPresent() && null != entry.getValue()) {
- setterMethod.get().invoke(result,
setterMethod.get().getParameterTypes()[0] == String.class
- ? String.valueOf(entry.getValue()) :
entry.getValue());
+ setDataSourceField(setterMethod.get(), result,
entry.getValue());
}
} catch (final IllegalArgumentException ex) {
throw new ShardingSphereConfigurationException("Incorrect
configuration item: the property %s of the dataSource, because %s",
entry.getKey(), ex.getMessage());
@@ -127,6 +127,21 @@ public final class DataSourceConfiguration {
return decorator.isPresent() ? decorator.get().decorate(result) :
result;
}
+ private void setDataSourceField(final Method method, final DataSource
target, final Object value) throws InvocationTargetException,
IllegalAccessException {
+ Class<?> paramType = method.getParameterTypes()[0];
+ if (paramType == int.class) {
+ method.invoke(target, Integer.parseInt(value.toString()));
+ } else if (paramType == long.class) {
+ method.invoke(target, Long.parseLong(value.toString()));
+ } else if (paramType == boolean.class || paramType == Boolean.class) {
+ method.invoke(target, Boolean.parseBoolean(value.toString()));
+ } else if (paramType == String.class) {
+ method.invoke(target, value.toString());
+ } else {
+ method.invoke(target, value);
+ }
+ }
+
@SuppressWarnings("rawtypes")
private Optional<JDBCParameterDecorator> findJDBCParameterDecorator(final
DataSource dataSource) {
return
ShardingSphereServiceLoader.getSingletonServiceInstances(JDBCParameterDecorator.class).stream().filter(each
-> each.getType() == dataSource.getClass()).findFirst();
diff --git
a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/config/datasource/DataSourceParameter.java
b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/config/datasource/DataSourceParameter.java
index bc73d33..04447ca 100644
---
a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/config/datasource/DataSourceParameter.java
+++
b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/config/datasource/DataSourceParameter.java
@@ -21,6 +21,8 @@ import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
+import java.util.Properties;
+
/**
* Data source parameters.
*/
@@ -48,4 +50,6 @@ public final class DataSourceParameter {
private long maintenanceIntervalMilliseconds = 30 * 1000L;
private boolean readOnly;
+
+ private Properties customPoolProps;
}
diff --git
a/shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/config/DataSourceConfigurationTest.java
b/shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/config/DataSourceConfigurationTest.java
index 93b9b7c..1efac4e 100644
---
a/shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/config/DataSourceConfigurationTest.java
+++
b/shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/config/DataSourceConfigurationTest.java
@@ -29,6 +29,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Properties;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.instanceOf;
@@ -188,4 +189,27 @@ public final class DataSourceConfigurationTest {
assertThat(actualConnectionInitSql, hasItem("set names utf8mb4;"));
assertThat(actualConnectionInitSql, hasItem("set names utf8;"));
}
+
+ @Test
+ public void assertCreateDataSourceWithCustomPoolProps() {
+ Map<String, Object> props = new HashMap<>(16, 1);
+ props.put("driverClassName", "org.h2.Driver");
+ props.put("jdbcUrl",
"jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MySQL");
+ props.put("username", "root");
+ props.put("password", "root");
+ props.put("loginTimeout", "5000");
+ Properties customPoolProps = new Properties();
+ customPoolProps.setProperty("maximumPoolSize", "30");
+ customPoolProps.setProperty("idleTimeout", "30000");
+ DataSourceConfiguration dataSourceConfig = new
DataSourceConfiguration(HikariDataSource.class.getName());
+ dataSourceConfig.getProps().putAll(props);
+ dataSourceConfig.getProps().putAll(new HashMap(customPoolProps));
+ HikariDataSource actual = (HikariDataSource)
dataSourceConfig.createDataSource();
+ assertThat(actual.getDriverClassName(), is("org.h2.Driver"));
+ assertThat(actual.getJdbcUrl(),
is("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MySQL"));
+ assertThat(actual.getUsername(), is("root"));
+ assertThat(actual.getPassword(), is("root"));
+ assertThat(actual.getMaximumPoolSize(), is(30));
+ assertThat(actual.getIdleTimeout(), is(30000L));
+ }
}
diff --git
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/connection/ConnectionUrlParser.java
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/connection/ConnectionUrlParser.java
new file mode 100644
index 0000000..8e7b88f
--- /dev/null
+++
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/connection/ConnectionUrlParser.java
@@ -0,0 +1,86 @@
+/*
+ * 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.proxy.backend.communication.jdbc.connection;
+
+import com.google.common.base.Splitter;
+import com.google.common.base.Strings;
+import lombok.Getter;
+import
org.apache.shardingsphere.infra.config.exception.ShardingSphereConfigurationException;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * JDBC connection url parser.
+ */
+@Getter
+public final class ConnectionUrlParser {
+
+ private static final String KEY_SCHEME = "scheme";
+
+ private static final String KEY_AUTHORITY = "authority";
+
+ private static final String KEY_PATH = "path";
+
+ private static final String KEY_QUERY = "query";
+
+ private static final Pattern CONNECTION_URL_PATTERN = Pattern.compile(
+ // scheme
+ "(?<scheme>[\\w\\+:%]+)\\s*"
+ // authority
+ + "(?://(?<authority>[^/?#]*))?\\s*"
+ // path
+ + "(?:/(?!\\s*/)(?<path>[^?#]*))?"
+ // query
+ + "(?:\\?(?!\\s*\\?)(?<query>[^#]*))?");
+
+ private final Matcher matcher;
+
+ private final String scheme;
+
+ private final String authority;
+
+ private final String path;
+
+ private final String query;
+
+ public ConnectionUrlParser(final String jdbcUrl) {
+ matcher = CONNECTION_URL_PATTERN.matcher(jdbcUrl);
+ if (!matcher.matches()) {
+ throw new ShardingSphereConfigurationException("Incorrect JDBC url
format: %s", jdbcUrl);
+ }
+ scheme = matcher.group(KEY_SCHEME);
+ authority = matcher.group(KEY_AUTHORITY);
+ path = matcher.group(KEY_PATH);
+ query = matcher.group(KEY_QUERY);
+ }
+
+ /**
+ * Get properties map of JDBC url.
+ *
+ * @return properties map
+ */
+ public Map<String, String> getQueryMap() {
+ if (!Strings.isNullOrEmpty(query)) {
+ return Splitter.on("&").withKeyValueSeparator("=").split(query);
+ }
+ return Collections.emptyMap();
+ }
+}
diff --git
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/decorator/HikariJDBCParameterDecorator.java
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/decorator/HikariJDBCParameterDecorator.java
index b1dc698..6c51081 100644
---
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/decorator/HikariJDBCParameterDecorator.java
+++
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/decorator/HikariJDBCParameterDecorator.java
@@ -17,8 +17,12 @@
package
org.apache.shardingsphere.proxy.backend.communication.jdbc.datasource.decorator;
+import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import
org.apache.shardingsphere.infra.config.datasource.JDBCParameterDecorator;
+import
org.apache.shardingsphere.proxy.backend.communication.jdbc.connection.ConnectionUrlParser;
+
+import java.util.Map;
/**
* JDBC parameter decorator for HikariCP.
@@ -27,23 +31,33 @@ public final class HikariJDBCParameterDecorator implements
JDBCParameterDecorato
@Override
public HikariDataSource decorate(final HikariDataSource dataSource) {
- dataSource.getDataSourceProperties().setProperty("useServerPrepStmts",
Boolean.TRUE.toString());
- dataSource.getDataSourceProperties().setProperty("cachePrepStmts",
Boolean.TRUE.toString());
- dataSource.getDataSourceProperties().setProperty("prepStmtCacheSize",
"200000");
-
dataSource.getDataSourceProperties().setProperty("prepStmtCacheSqlLimit",
"2048");
-
dataSource.getDataSourceProperties().setProperty("useLocalSessionState",
Boolean.TRUE.toString());
-
dataSource.getDataSourceProperties().setProperty("rewriteBatchedStatements",
Boolean.TRUE.toString());
-
dataSource.getDataSourceProperties().setProperty("cacheResultSetMetadata",
Boolean.FALSE.toString());
-
dataSource.getDataSourceProperties().setProperty("cacheServerConfiguration",
Boolean.TRUE.toString());
-
dataSource.getDataSourceProperties().setProperty("elideSetAutoCommits",
Boolean.TRUE.toString());
- dataSource.getDataSourceProperties().setProperty("maintainTimeStats",
Boolean.FALSE.toString());
-
dataSource.getDataSourceProperties().setProperty("netTimeoutForStreamingResults",
"0");
- dataSource.getDataSourceProperties().setProperty("tinyInt1isBit",
Boolean.FALSE.toString());
+ Map<String, String> urlProps = new
ConnectionUrlParser(dataSource.getJdbcUrl()).getQueryMap();
+ addJDBCProperty(dataSource, urlProps, "useServerPrepStmts",
Boolean.TRUE.toString());
+ addJDBCProperty(dataSource, urlProps, "useServerPrepStmts",
Boolean.TRUE.toString());
+ addJDBCProperty(dataSource, urlProps, "cachePrepStmts",
Boolean.TRUE.toString());
+ addJDBCProperty(dataSource, urlProps, "prepStmtCacheSize", "200000");
+ addJDBCProperty(dataSource, urlProps, "prepStmtCacheSqlLimit", "2048");
+ addJDBCProperty(dataSource, urlProps, "useLocalSessionState",
Boolean.TRUE.toString());
+ addJDBCProperty(dataSource, urlProps, "rewriteBatchedStatements",
Boolean.TRUE.toString());
+ addJDBCProperty(dataSource, urlProps, "cacheResultSetMetadata",
Boolean.FALSE.toString());
+ addJDBCProperty(dataSource, urlProps, "cacheServerConfiguration",
Boolean.TRUE.toString());
+ addJDBCProperty(dataSource, urlProps, "elideSetAutoCommits",
Boolean.TRUE.toString());
+ addJDBCProperty(dataSource, urlProps, "maintainTimeStats",
Boolean.FALSE.toString());
+ addJDBCProperty(dataSource, urlProps, "netTimeoutForStreamingResults",
"0");
+ addJDBCProperty(dataSource, urlProps, "tinyInt1isBit",
Boolean.FALSE.toString());
+ addJDBCProperty(dataSource, urlProps, "useSSL",
Boolean.FALSE.toString());
+ addJDBCProperty(dataSource, urlProps, "serverTimezone", "UTC");
HikariDataSource result = new HikariDataSource(dataSource);
dataSource.close();
return result;
}
+ private void addJDBCProperty(final HikariConfig config, final Map<String,
String> urlProps, final String key, final String value) {
+ if (urlProps.isEmpty() || !urlProps.containsKey(key)) {
+ config.addDataSourceProperty(key, value);
+ }
+ }
+
@Override
public Class<HikariDataSource> getType() {
return HikariDataSource.class;
diff --git
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/connection/ConnectionUrlParserTest.java
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/connection/ConnectionUrlParserTest.java
new file mode 100644
index 0000000..c8f7c1b
--- /dev/null
+++
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/connection/ConnectionUrlParserTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.proxy.backend.communication.jdbc.connection;
+
+import lombok.extern.slf4j.Slf4j;
+import
org.apache.shardingsphere.infra.config.exception.ShardingSphereConfigurationException;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+@Slf4j
+public final class ConnectionUrlParserTest {
+
+ private static final String MYSQL_CONNECTION_WITHOUT_PROPS =
"jdbc:mysql://127.0.0.1:3306/demo_ds";
+
+ private static final String MYSQL_CONNECTION_WITH_PROPS =
"jdbc:mysql://127.0.0.1:3306/demo_ds?serverTimezone=UTC&useSSL=false";
+
+ private static final String MYSQL_CONNECTION_WITH_REPLICATION =
"jdbc:mysql:replication://master_ip:3306,slave_1_ip:3306,slave_2_ip:3306/demo_ds?useUnicode=true";
+
+ private static final String POSTGRESQL_CONNECTION_WITH_PROPS =
"jdbc:postgresql://127.0.0.1:5432/demo_ds?serverTimezone=UTC&useSSL=false";
+
+ private static final String MICROSOFT_SQLSERVER_CONNECTION_WITHOUT_PROPS =
"jdbc:microsoft:sqlserver://127.0.0.1:3306/demo_ds";
+
+ private static final String MOCK_CONNECTION_WITHOUT_PROPS =
"mock:jdbc://127.0.0.1:3306/demo_ds";
+
+ private static final String INCORRECT_MYSQL_CONNECTION =
"jdbc:mysql://127.0.0.1:3306//demo_ds";
+
+ @Test
+ public void assertParseMySQLWithoutProps() {
+ ConnectionUrlParser connectionUrlParser = new
ConnectionUrlParser(MYSQL_CONNECTION_WITHOUT_PROPS);
+ assertThat(connectionUrlParser.getScheme(), is("jdbc:mysql:"));
+ assertThat(connectionUrlParser.getAuthority(), is("127.0.0.1:3306"));
+ assertThat(connectionUrlParser.getPath(), is("demo_ds"));
+ assertNull(connectionUrlParser.getQuery());
+ assertTrue(connectionUrlParser.getQueryMap().isEmpty());
+ }
+
+ @Test
+ public void assertParseMySQLWithProps() {
+ ConnectionUrlParser connectionUrlParser = new
ConnectionUrlParser(MYSQL_CONNECTION_WITH_PROPS);
+ assertThat(connectionUrlParser.getScheme(), is("jdbc:mysql:"));
+ assertThat(connectionUrlParser.getAuthority(), is("127.0.0.1:3306"));
+ assertThat(connectionUrlParser.getPath(), is("demo_ds"));
+ assertThat(connectionUrlParser.getQuery(),
is("serverTimezone=UTC&useSSL=false"));
+ assertThat(connectionUrlParser.getQueryMap().size(), is(2));
+ assertThat(connectionUrlParser.getQueryMap().get("serverTimezone"),
is("UTC"));
+ assertThat(connectionUrlParser.getQueryMap().get("useSSL"),
is("false"));
+ }
+
+ @Test
+ public void assertParseMySQLWithReplication() {
+ ConnectionUrlParser connectionUrlParser = new
ConnectionUrlParser(MYSQL_CONNECTION_WITH_REPLICATION);
+ assertThat(connectionUrlParser.getScheme(),
is("jdbc:mysql:replication:"));
+ assertThat(connectionUrlParser.getAuthority(),
is("master_ip:3306,slave_1_ip:3306,slave_2_ip:3306"));
+ assertThat(connectionUrlParser.getPath(), is("demo_ds"));
+ assertThat(connectionUrlParser.getQuery(), is("useUnicode=true"));
+ assertThat(connectionUrlParser.getQueryMap().size(), is(1));
+ assertThat(connectionUrlParser.getQueryMap().get("useUnicode"),
is("true"));
+ }
+
+ @Test
+ public void assertParsePostgreSQLWithProps() {
+ ConnectionUrlParser connectionUrlParser = new
ConnectionUrlParser(POSTGRESQL_CONNECTION_WITH_PROPS);
+ assertThat(connectionUrlParser.getScheme(), is("jdbc:postgresql:"));
+ assertThat(connectionUrlParser.getAuthority(), is("127.0.0.1:5432"));
+ assertThat(connectionUrlParser.getPath(), is("demo_ds"));
+ assertThat(connectionUrlParser.getQuery(),
is("serverTimezone=UTC&useSSL=false"));
+ assertThat(connectionUrlParser.getQueryMap().size(), is(2));
+ assertThat(connectionUrlParser.getQueryMap().get("serverTimezone"),
is("UTC"));
+ assertThat(connectionUrlParser.getQueryMap().get("useSSL"),
is("false"));
+ }
+
+ @Test
+ public void assertParseMicrosoftSQLServerWithoutProps() {
+ ConnectionUrlParser connectionUrlParser = new
ConnectionUrlParser(MICROSOFT_SQLSERVER_CONNECTION_WITHOUT_PROPS);
+ assertThat(connectionUrlParser.getScheme(),
is("jdbc:microsoft:sqlserver:"));
+ assertThat(connectionUrlParser.getAuthority(), is("127.0.0.1:3306"));
+ assertThat(connectionUrlParser.getPath(), is("demo_ds"));
+ assertNull(connectionUrlParser.getQuery());
+ assertTrue(connectionUrlParser.getQueryMap().isEmpty());
+ }
+
+ @Test
+ public void assertParseMockSQLWithoutProps() {
+ ConnectionUrlParser connectionUrlParser = new
ConnectionUrlParser(MOCK_CONNECTION_WITHOUT_PROPS);
+ assertThat(connectionUrlParser.getScheme(), is("mock:jdbc:"));
+ assertThat(connectionUrlParser.getAuthority(), is("127.0.0.1:3306"));
+ assertThat(connectionUrlParser.getPath(), is("demo_ds"));
+ assertNull(connectionUrlParser.getQuery());
+ assertTrue(connectionUrlParser.getQueryMap().isEmpty());
+ }
+
+ @Test(expected = ShardingSphereConfigurationException.class)
+ public void assertParseIncorrectURL() {
+ new ConnectionUrlParser(INCORRECT_MYSQL_CONNECTION);
+ }
+}
diff --git
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/decorator/HikariJDBCParameterDecoratorTest.java
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/decorator/HikariJDBCParameterDecoratorTest.java
index 5a6ce20..50a4d93 100644
---
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/decorator/HikariJDBCParameterDecoratorTest.java
+++
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/decorator/HikariJDBCParameterDecoratorTest.java
@@ -25,6 +25,7 @@ import java.util.Properties;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertNull;
public final class HikariJDBCParameterDecoratorTest {
@@ -52,5 +53,30 @@ public final class HikariJDBCParameterDecoratorTest {
assertThat(props.getProperty("maintainTimeStats"),
is(Boolean.FALSE.toString()));
assertThat(props.getProperty("netTimeoutForStreamingResults"),
is("0"));
assertThat(props.getProperty("tinyInt1isBit"),
is(Boolean.FALSE.toString()));
+ assertThat(props.getProperty("useSSL"), is(Boolean.FALSE.toString()));
+ assertThat(props.getProperty("serverTimezone"), is("UTC"));
+ }
+
+ @Test
+ public void assertDecoratedHikariDataSourceWithExistedParam() {
+ HikariDataSource dataSource = new HikariDataSource();
+
dataSource.setDriverClassName("org.apache.shardingsphere.test.mock.MockedDriver");
+
dataSource.setJdbcUrl("mock:jdbc://127.0.0.1:3306/test0?tinyInt1isBit=true&useSSL=false");
+ HikariDataSource actual = new
HikariJDBCParameterDecorator().decorate(dataSource);
+ Properties props = actual.getDataSourceProperties();
+ assertThat(props.getProperty("useServerPrepStmts"),
is(Boolean.TRUE.toString()));
+ assertThat(props.getProperty("cachePrepStmts"),
is(Boolean.TRUE.toString()));
+ assertThat(props.getProperty("prepStmtCacheSize"), is("200000"));
+ assertThat(props.getProperty("prepStmtCacheSqlLimit"), is("2048"));
+ assertThat(props.getProperty("useLocalSessionState"),
is(Boolean.TRUE.toString()));
+ assertThat(props.getProperty("rewriteBatchedStatements"),
is(Boolean.TRUE.toString()));
+ assertThat(props.getProperty("cacheResultSetMetadata"),
is(Boolean.FALSE.toString()));
+ assertThat(props.getProperty("cacheServerConfiguration"),
is(Boolean.TRUE.toString()));
+ assertThat(props.getProperty("elideSetAutoCommits"),
is(Boolean.TRUE.toString()));
+ assertThat(props.getProperty("maintainTimeStats"),
is(Boolean.FALSE.toString()));
+ assertThat(props.getProperty("netTimeoutForStreamingResults"),
is("0"));
+ assertNull(props.getProperty("tinyInt1isBit"));
+ assertNull(props.getProperty("useSSL"));
+ assertThat(props.getProperty("serverTimezone"), is("UTC"));
}
}
diff --git
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AddResourceBackendHandlerTest.java
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AddResourceBackendHandlerTest.java
index 016ebf6..70896e4 100644
---
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AddResourceBackendHandlerTest.java
+++
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/rdl/resource/AddResourceBackendHandlerTest.java
@@ -94,6 +94,6 @@ public final class AddResourceBackendHandlerTest {
}
private AddResourceStatement createAddResourceStatement() {
- return new AddResourceStatement(Collections.singleton(new
DataSourceSegment("ds_0", "127.0.0.1", "test0", "3306", "root", "", new
Properties())));
+ return new AddResourceStatement(Collections.singleton(new
DataSourceSegment("ds_0", "jdbc:mysql://127.0.0.1:3306/test0", null, null,
null, "root", "", new Properties())));
}
}
diff --git
a/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/config/util/DataSourceParameterConverter.java
b/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/config/util/DataSourceParameterConverter.java
index ec3be57..d76230b 100644
---
a/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/config/util/DataSourceParameterConverter.java
+++
b/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/config/util/DataSourceParameterConverter.java
@@ -25,6 +25,7 @@ import
org.apache.shardingsphere.infra.config.datasource.DataSourceParameter;
import org.apache.shardingsphere.proxy.config.yaml.YamlDataSourceParameter;
import java.lang.reflect.Field;
+import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
@@ -85,6 +86,9 @@ public final class DataSourceParameterConverter {
result.setPassword(yamlDataSourceParameter.getPassword());
result.setReadOnly(yamlDataSourceParameter.isReadOnly());
result.setUrl(yamlDataSourceParameter.getUrl());
+ if (null != yamlDataSourceParameter.getCustomPoolProps()) {
+
result.setCustomPoolProps(yamlDataSourceParameter.getCustomPoolProps());
+ }
return result;
}
@@ -119,6 +123,9 @@ public final class DataSourceParameterConverter {
result.getProps().put("minPoolSize",
dataSourceParameter.getMinPoolSize());
result.getProps().put("maintenanceIntervalMilliseconds",
dataSourceParameter.getMaintenanceIntervalMilliseconds());
result.getProps().put("readOnly", dataSourceParameter.isReadOnly());
+ if (null != dataSourceParameter.getCustomPoolProps()) {
+ result.getProps().putAll(new
HashMap(dataSourceParameter.getCustomPoolProps()));
+ }
return result;
}
}
diff --git
a/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/config/yaml/YamlDataSourceParameter.java
b/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/config/yaml/YamlDataSourceParameter.java
index 8afdf94..ea159cf 100644
---
a/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/config/yaml/YamlDataSourceParameter.java
+++
b/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/config/yaml/YamlDataSourceParameter.java
@@ -22,6 +22,8 @@ import lombok.Getter;
import lombok.Setter;
import org.apache.shardingsphere.infra.yaml.config.YamlConfiguration;
+import java.util.Properties;
+
/**
* Data source parameters for YAML.
*/
@@ -49,4 +51,6 @@ public final class YamlDataSourceParameter implements
YamlConfiguration {
private long maintenanceIntervalMilliseconds;
private boolean readOnly;
+
+ private Properties customPoolProps;
}
diff --git
a/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/converter/AddResourcesStatementConverter.java
b/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/converter/AddResourcesStatementConverter.java
index d736b43..ba0f95b 100644
---
a/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/converter/AddResourcesStatementConverter.java
+++
b/shardingsphere-proxy/shardingsphere-proxy-common/src/main/java/org/apache/shardingsphere/proxy/converter/AddResourcesStatementConverter.java
@@ -54,12 +54,16 @@ public final class AddResourcesStatementConverter {
dataSource.setConnectionTimeoutMilliseconds(parameter.getConnectionTimeoutMilliseconds());
dataSource.setIdleTimeoutMilliseconds(parameter.getIdleTimeoutMilliseconds());
dataSource.setMaintenanceIntervalMilliseconds(parameter.getMaintenanceIntervalMilliseconds());
+ dataSource.setCustomPoolProps(each.getProperties());
result.put(each.getName(), dataSource);
}
return result;
}
private static String getURL(final DatabaseType databaseType, final
DataSourceSegment dataSourceSegment) {
+ if (null != dataSourceSegment.getUrl()) {
+ return dataSourceSegment.getUrl();
+ }
return String.format("%s//%s:%s/%s",
databaseType.getJdbcUrlPrefixes().iterator().next(),
dataSourceSegment.getHostName(), dataSourceSegment.getPort(),
dataSourceSegment.getDb());
}
}
diff --git
a/shardingsphere-proxy/shardingsphere-proxy-common/src/test/java/org/apache/shardingsphere/proxy/config/util/DataSourceParameterConverterTest.java
b/shardingsphere-proxy/shardingsphere-proxy-common/src/test/java/org/apache/shardingsphere/proxy/config/util/DataSourceParameterConverterTest.java
index 128e01b..f6d967e 100644
---
a/shardingsphere-proxy/shardingsphere-proxy-common/src/test/java/org/apache/shardingsphere/proxy/config/util/DataSourceParameterConverterTest.java
+++
b/shardingsphere-proxy/shardingsphere-proxy-common/src/test/java/org/apache/shardingsphere/proxy/config/util/DataSourceParameterConverterTest.java
@@ -25,6 +25,7 @@ import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
+import java.util.Properties;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
@@ -80,14 +81,16 @@ public final class DataSourceParameterConverterTest {
@Test
public void assertGetDataSourceParameterMapFromYamlConfiguration() {
- Map<String, YamlDataSourceParameter> yamlDataSourceParameterMap = new
HashMap<>();
YamlDataSourceParameter yamlDataSourceParameter0 = new
YamlDataSourceParameter();
yamlDataSourceParameter0.setUrl("jdbc:mysql://localhost:3306/t_order");
+ yamlDataSourceParameter0.setCustomPoolProps(getCustomPoolProps());
setYamlDataSourceParameterPropertyWithoutUrl(yamlDataSourceParameter0);
- yamlDataSourceParameterMap.put("ds_0", yamlDataSourceParameter0);
YamlDataSourceParameter yamlDataSourceParameter1 = new
YamlDataSourceParameter();
yamlDataSourceParameter1.setUrl("jdbc:mysql://localhost:3306/t_order_item");
+ yamlDataSourceParameter1.setCustomPoolProps(getCustomPoolProps());
setYamlDataSourceParameterPropertyWithoutUrl(yamlDataSourceParameter1);
+ Map<String, YamlDataSourceParameter> yamlDataSourceParameterMap = new
HashMap<>();
+ yamlDataSourceParameterMap.put("ds_0", yamlDataSourceParameter0);
yamlDataSourceParameterMap.put("ds_1", yamlDataSourceParameter1);
Map<String, DataSourceParameter> actualDataSourceParameterMap =
DataSourceParameterConverter.getDataSourceParameterMapFromYamlConfiguration(yamlDataSourceParameterMap);
assertThat(actualDataSourceParameterMap.size(), is(2));
@@ -117,5 +120,15 @@ public final class DataSourceParameterConverterTest {
assertThat(dataSourceParameter.getMaintenanceIntervalMilliseconds(),
is(30 * 1000L));
assertThat(dataSourceParameter.getUsername(), is("root"));
assertThat(dataSourceParameter.getPassword(), is("root"));
+ assertThat(dataSourceParameter.getCustomPoolProps().size(), is(2));
+
assertThat(dataSourceParameter.getCustomPoolProps().get("maxPoolSize"), is(30));
+
assertThat(dataSourceParameter.getCustomPoolProps().get("idleTimeoutMilliseconds"),
is("30000"));
+ }
+
+ private Properties getCustomPoolProps() {
+ Properties result = new Properties();
+ result.put("maxPoolSize", 30);
+ result.put("idleTimeoutMilliseconds", "30000");
+ return result;
}
}
diff --git
a/shardingsphere-proxy/shardingsphere-proxy-common/src/test/java/org/apache/shardingsphere/proxy/converter/AddResourcesStatementConverterTest.java
b/shardingsphere-proxy/shardingsphere-proxy-common/src/test/java/org/apache/shardingsphere/proxy/converter/AddResourcesStatementConverterTest.java
index 0d36e39..5451c0c 100644
---
a/shardingsphere-proxy/shardingsphere-proxy-common/src/test/java/org/apache/shardingsphere/proxy/converter/AddResourcesStatementConverterTest.java
+++
b/shardingsphere-proxy/shardingsphere-proxy-common/src/test/java/org/apache/shardingsphere/proxy/converter/AddResourcesStatementConverterTest.java
@@ -41,13 +41,15 @@ public final class AddResourcesStatementConverterTest {
assertThat(actual.size(), is(2));
assertTrue(actual.keySet().containsAll(Arrays.asList("ds0", "ds1")));
assertThat(actual.values().iterator().next().getUsername(),
is("root0"));
+
assertThat(actual.values().iterator().next().getCustomPoolProps().getProperty("maxPoolSize"),
is("30"));
}
private Collection<DataSourceSegment> createDataSourceSegments() {
Collection<DataSourceSegment> result = new LinkedList<>();
- for (int i = 0; i < 2; i++) {
- result.add(new DataSourceSegment(String.format("ds%s", i),
"127.0.0.1", "3306", String.format("demo_ds_%s", i), String.format("root%s",
i), String.format("root%s", i), new Properties()));
- }
+ Properties customPoolProps = new Properties();
+ customPoolProps.setProperty("maxPoolSize", "30");
+ result.add(new DataSourceSegment("ds0", null, "127.0.0.1", "3306",
"demo_ds_0", "root0", "root0", customPoolProps));
+ result.add(new DataSourceSegment("ds1",
"jdbc:mysql://127.0.0.1:3306/demo_ds_1?useSSL=false", null, null, null,
"root1", "root1", customPoolProps));
return result;
}
}
diff --git
a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/distsql/DataSourceAssert.java
b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/distsql/DataSourceAssert.java
index e16c4ba..7f65c71 100644
---
a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/distsql/DataSourceAssert.java
+++
b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/distsql/DataSourceAssert.java
@@ -49,6 +49,8 @@ public final class DataSourceAssert {
assertThat(assertContext.getText(String.format("`%s`'s datasource
segment assertion error: ",
actual.getClass().getSimpleName())), actual.getName(),
CoreMatchers.is(expected.getName()));
assertThat(assertContext.getText(String.format("`%s`'s datasource
segment assertion error: ",
+ actual.getClass().getSimpleName())), actual.getUrl(),
CoreMatchers.is(expected.getUrl()));
+ assertThat(assertContext.getText(String.format("`%s`'s datasource
segment assertion error: ",
actual.getClass().getSimpleName())), actual.getHostName(),
CoreMatchers.is(expected.getHostName()));
assertThat(assertContext.getText(String.format("`%s`'s datasource
segment assertion error: ",
actual.getClass().getSimpleName())), actual.getPort(),
CoreMatchers.is(expected.getPort()));
diff --git
a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/segment/impl/distsql/ExpectedDataSource.java
b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/segment/impl/distsql/ExpectedDataSource.java
index 324822c..7f9e32f 100644
---
a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/segment/impl/distsql/ExpectedDataSource.java
+++
b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/segment/impl/distsql/ExpectedDataSource.java
@@ -30,6 +30,9 @@ import javax.xml.bind.annotation.XmlAttribute;
@Setter
public final class ExpectedDataSource extends
AbstractExpectedIdentifierSQLSegment {
+ @XmlAttribute
+ private String url;
+
@XmlAttribute(name = "host-name")
private String hostName;
diff --git
a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/rdl/create.xml
b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/rdl/create.xml
index 121021a..7fe38c4 100644
---
a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/rdl/create.xml
+++
b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/rdl/create.xml
@@ -17,19 +17,32 @@
-->
<sql-parser-test-cases>
- <add-resource sql-case-id="add-resource-single-without-password">
+ <add-resource sql-case-id="add-resource-simple-single-without-password">
<data-source name="ds_0" host-name="127.0.0.1" port="3306" db="test0"
user="ROOT" password=""/>
</add-resource>
- <add-resource sql-case-id="add-resource-single-with-password">
+ <add-resource sql-case-id="add-resource-simple-single-with-password">
<data-source name="ds_0" host-name="127.0.0.1" port="3306" db="test0"
user="ROOT" password="123456"/>
</add-resource>
- <add-resource sql-case-id="add-resource-multiple">
+ <add-resource sql-case-id="add-resource-simple-multiple">
<data-source name="ds_0" host-name="127.0.0.1" port="3306" db="test0"
user="ROOT" password="123456"/>
<data-source name="ds_1" host-name="127.0.0.1" port="3306" db="test1"
user="ROOT" password="123456"/>
</add-resource>
+ <add-resource sql-case-id="add-resource-url-single-without-password">
+ <data-source name="ds_0" url="jdbc:mysql://127.0.0.1:3306/test0"
user="ROOT" password=""/>
+ </add-resource>
+
+ <add-resource sql-case-id="add-resource-url-single-with-password">
+ <data-source name="ds_0" url="jdbc:mysql://127.0.0.1:3306/test0"
user="ROOT" password="123456"/>
+ </add-resource>
+
+ <add-resource sql-case-id="add-resource-url-multiple">
+ <data-source name="ds_0" url="jdbc:mysql://127.0.0.1:3306/test0"
user="ROOT" password="123456"/>
+ <data-source name="ds_1" url="jdbc:mysql://127.0.0.1:3306/test1"
user="ROOT" password="123456"/>
+ </add-resource>
+
<create-sharding-table-rule sql-case-id="create-sharding-table-rule">
<rule name="t_order" table-strategy-column="order_id"
key-generate-strategy-column="another_id">
<data-source>ms_group_0</data-source>
diff --git
a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/sql/supported/rdl/create.xml
b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/sql/supported/rdl/create.xml
index 2001fc9..1e1f12a 100644
---
a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/sql/supported/rdl/create.xml
+++
b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/sql/supported/rdl/create.xml
@@ -17,9 +17,12 @@
-->
<sql-cases>
- <distsql-case id="add-resource-single-without-password" value="ADD
RESOURCE ds_0(HOST=127.0.0.1,PORT=3306,DB=test0,USER=ROOT);" />
- <distsql-case id="add-resource-single-with-password" value="ADD RESOURCE
ds_0(HOST=127.0.0.1,PORT=3306,DB=test0,USER=ROOT,PASSWORD=123456);" />
- <distsql-case id="add-resource-multiple" value="ADD RESOURCE
ds_0(HOST=127.0.0.1,PORT=3306,DB=test0,USER=ROOT,PASSWORD=123456),
ds_1(HOST=127.0.0.1,PORT=3306,DB=test1,USER=ROOT,PASSWORD=123456);" />
+ <distsql-case id="add-resource-simple-single-without-password" value="ADD
RESOURCE ds_0(HOST=127.0.0.1,PORT=3306,DB=test0,USER=ROOT);" />
+ <distsql-case id="add-resource-simple-single-with-password" value="ADD
RESOURCE ds_0(HOST=127.0.0.1,PORT=3306,DB=test0,USER=ROOT,PASSWORD=123456);" />
+ <distsql-case id="add-resource-simple-multiple" value="ADD RESOURCE
ds_0(HOST=127.0.0.1,PORT=3306,DB=test0,USER=ROOT,PASSWORD=123456),
ds_1(HOST=127.0.0.1,PORT=3306,DB=test1,USER=ROOT,PASSWORD=123456);" />
+ <distsql-case id="add-resource-url-single-without-password" value="ADD
RESOURCE ds_0(URL='jdbc:mysql://127.0.0.1:3306/test0',USER=ROOT);\" />
+ <distsql-case id="add-resource-url-single-with-password" value="ADD
RESOURCE
ds_0(URL='jdbc:mysql://127.0.0.1:3306/test0',USER=ROOT,PASSWORD=123456);" />
+ <distsql-case id="add-resource-url-multiple" value="ADD RESOURCE
ds_0(URL='jdbc:mysql://127.0.0.1:3306/test0',USER=ROOT,PASSWORD=123456),
ds_1(URL='jdbc:mysql://127.0.0.1:3306/test1',USER=ROOT,PASSWORD=123456);" />
<distsql-case id="create-sharding-table-rule" value="CREATE SHARDING TABLE
RULE t_order (RESOURCES(ms_group_0,ms_group_1),
SHARDING_COLUMN=order_id,TYPE(NAME=hash_mod,PROPERTIES('sharding-count'=4)),
GENERATED_KEY(COLUMN=another_id,TYPE(NAME=snowflake,PROPERTIES('worker-id'=123))))"
/>
<distsql-case id="create-sharding-binding-table-rule" value="CREATE
SHARDING BINDING TABLE RULES ((t_order,t_order_item), (t_1,t_2))" />
<distsql-case id="create-sharding-broadcast-table-rule" value="CREATE
SHARDING BROADCAST TABLE RULES(t_1,t_2)" />