This is an automated email from the ASF dual-hosted git repository.
linghengqian 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 b8cd91dd940 URLArgumentLine to support multiple expressions on the one
line (#32817)
b8cd91dd940 is described below
commit b8cd91dd940b09866951d3b49d95d2db60ae3d19
Author: malonglei <[email protected]>
AuthorDate: Thu Sep 12 12:56:05 2024 +0800
URLArgumentLine to support multiple expressions on the one line (#32817)
* URLArgumentLine to support multiple expressions on the one line
* URLArgumentLine to support multiple expressions on the one line
* URLArgumentLine to support multiple expressions on the one line
* add multiple dynamic placeholders document
---
.../jdbc-driver/known-implementation/_index.cn.md | 33 +++++++++++++++++++
.../jdbc-driver/known-implementation/_index.en.md | 33 +++++++++++++++++++
.../infra/url/core/arg/URLArgumentLine.java | 38 ++++++++++++----------
.../infra/url/core/arg/URLArgumentLineTest.java | 24 ++++++++++++++
4 files changed, 111 insertions(+), 17 deletions(-)
diff --git
a/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/known-implementation/_index.cn.md
b/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/known-implementation/_index.cn.md
index 3156c0990ab..85dd493a0cc 100644
---
a/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/known-implementation/_index.cn.md
+++
b/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/known-implementation/_index.cn.md
@@ -175,6 +175,39 @@ public class ExampleUtils {
- `jdbc:shardingsphere:classpath:config.yaml?placeholder-type=system_props`
-
`jdbc:shardingsphere:absolutepath:/path/to/config.yaml?placeholder-type=system_props`
+### 多个动态占位符
+
+在配置 YAML 属性值的时候,如果 YAML 属性值的部分需要动态替换,可以通过配置多个动态占位符的方式来实现
+
+假设存在以下一组环境变量或系统属性,
+
+1. 存在环境变量或系统属性 `FIXTURE_HOST` 为 `127.0.0.1`。
+2. 存在环境变量或系统属性 `FIXTURE_PORT` 为 `3306`。
+3. 存在环境变量或系统属性 `FIXTURE_DATABASE` 为 `test`。
+4. 存在环境变量或系统属性 `FIXTURE_USERNAME` 为 `sa`。
+
+则对于以下 YAML 文件的截取片段,
+
+```yaml
+ds_1:
+ dataSourceClassName: com.zaxxer.hikari.HikariDataSource
+ driverClassName: $${FIXTURE_DRIVER_CLASS_NAME::com.mysql.cj.jdbc.Driver}
+ jdbcUrl:
jdbc:mysql://$${FIXTURE_HOST::}:$${FIXTURE_PORT::}/$${FIXTURE_DATABASE::}?useUnicode=true&characterEncoding=UTF-8
+ username: $${FIXTURE_USERNAME::}
+ password: $${FIXTURE_PASSWORD::}
+```
+
+此 YAML 截取片段将被解析为,
+
+```yaml
+ds_1:
+ dataSourceClassName: com.zaxxer.hikari.HikariDataSource
+ driverClassName: com.mysql.cj.jdbc.Driver
+ jdbcUrl:
jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8
+ username: sa
+ password:
+```
+
## 其他实现
具体可参考 https://github.com/apache/shardingsphere-plugin 。
diff --git
a/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/known-implementation/_index.en.md
b/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/known-implementation/_index.en.md
index a46fc6ade51..71f45f804f5 100644
---
a/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/known-implementation/_index.en.md
+++
b/docs/document/content/user-manual/shardingsphere-jdbc/yaml-config/jdbc-driver/known-implementation/_index.en.md
@@ -193,6 +193,39 @@ Example:
- `jdbc:shardingsphere:classpath:config.yaml?placeholder-type=system_props`
-
`jdbc:shardingsphere:absolutepath:/path/to/config.yaml?placeholder-type=system_props`
+### multiple dynamic placeholders
+
+When configuring the value of a YAML attribute, if part of the value of the
YAML attribute needs to be replaced dynamically, you can implement this by
configuring multiple dynamic placeholders.
+
+Assume the following set of environment variables or system properties exists,
+
+1. The existing environment variable or system property `FIXTURE_HOST` is
`127.0.0.1`。
+2. The existing environment variable or system property `FIXTURE_PORT` is
`3306`。
+3. The existing environment variable or system property `FIXTURE_DATABASE` is
`test`。
+4. The existing environment variable or system property `FIXTURE_USERNAME` is
`sa`。
+
+Then for the intercepted fragment of the following YAML file,
+
+```yaml
+ds_1:
+ dataSourceClassName: com.zaxxer.hikari.HikariDataSource
+ driverClassName: $${FIXTURE_DRIVER_CLASS_NAME::com.mysql.cj.jdbc.Driver}
+ jdbcUrl:
jdbc:mysql://$${FIXTURE_HOST::}:$${FIXTURE_PORT::}/$${FIXTURE_DATABASE::}?useUnicode=true&characterEncoding=UTF-8
+ username: $${FIXTURE_USERNAME::}
+ password: $${FIXTURE_PASSWORD::}
+```
+
+This YAML snippet will be parsed as,
+
+```yaml
+ds_1:
+ dataSourceClassName: com.zaxxer.hikari.HikariDataSource
+ driverClassName: com.mysql.cj.jdbc.Driver
+ jdbcUrl:
jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8
+ username: sa
+ password:
+```
+
## Other implementations
For details, please refer to https://github.com/apache/shardingsphere-plugin.
diff --git
a/infra/url/core/src/main/java/org/apache/shardingsphere/infra/url/core/arg/URLArgumentLine.java
b/infra/url/core/src/main/java/org/apache/shardingsphere/infra/url/core/arg/URLArgumentLine.java
index 3d339a6cfee..fcbd8b1763e 100644
---
a/infra/url/core/src/main/java/org/apache/shardingsphere/infra/url/core/arg/URLArgumentLine.java
+++
b/infra/url/core/src/main/java/org/apache/shardingsphere/infra/url/core/arg/URLArgumentLine.java
@@ -31,13 +31,7 @@ import java.util.regex.Pattern;
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public final class URLArgumentLine {
- private static final Pattern PLACEHOLDER_PATTERN =
Pattern.compile("\\$\\$\\{(.+::.*)}$");
-
- private static final String KV_SEPARATOR = "::";
-
- private final String argName;
-
- private final String argDefaultValue;
+ private static final Pattern PLACEHOLDER_PATTERN =
Pattern.compile("\\$\\$\\{(.*?)::(.*?)}");
private final Matcher placeholderMatcher;
@@ -52,8 +46,7 @@ public final class URLArgumentLine {
if (!matcher.find()) {
return Optional.empty();
}
- String[] parsedArg = matcher.group(1).split(KV_SEPARATOR, 2);
- return Optional.of(new URLArgumentLine(parsedArg[0], parsedArg[1],
matcher));
+ return Optional.of(new URLArgumentLine(matcher));
}
/**
@@ -63,18 +56,29 @@ public final class URLArgumentLine {
* @return replaced argument
*/
public String replaceArgument(final URLArgumentPlaceholderType type) {
- String argumentValue = getArgumentValue(type);
- if (!Strings.isNullOrEmpty(argumentValue)) {
- return placeholderMatcher.replaceAll(argumentValue);
+ placeholderMatcher.reset();
+ StringBuffer result = new StringBuffer();
+ while (placeholderMatcher.find()) {
+ String variableName = placeholderMatcher.group(1);
+ String defaultValue = placeholderMatcher.group(2);
+ String argumentValue = getArgumentValue(variableName, type);
+ if (Strings.isNullOrEmpty(argumentValue)) {
+ argumentValue = defaultValue;
+ }
+ placeholderMatcher.appendReplacement(result, argumentValue);
}
- if (!argDefaultValue.isEmpty()) {
- return placeholderMatcher.replaceAll(argDefaultValue);
+ placeholderMatcher.appendTail(result);
+ return rightTrim(result);
+ }
+
+ private String rightTrim(final StringBuffer result) {
+ while (result.length() > 0 &&
Character.isWhitespace(result.charAt(result.length() - 1))) {
+ result.deleteCharAt(result.length() - 1);
}
- String modifiedLineWithSpace = placeholderMatcher.replaceAll("");
- return modifiedLineWithSpace.substring(0,
modifiedLineWithSpace.length() - 1);
+ return result.toString();
}
- private String getArgumentValue(final URLArgumentPlaceholderType type) {
+ private String getArgumentValue(final String argName, final
URLArgumentPlaceholderType type) {
if (URLArgumentPlaceholderType.ENVIRONMENT == type) {
return System.getenv(argName);
}
diff --git
a/infra/url/core/src/test/java/org/apache/shardingsphere/infra/url/core/arg/URLArgumentLineTest.java
b/infra/url/core/src/test/java/org/apache/shardingsphere/infra/url/core/arg/URLArgumentLineTest.java
index acd0505683c..898b7f4f084 100644
---
a/infra/url/core/src/test/java/org/apache/shardingsphere/infra/url/core/arg/URLArgumentLineTest.java
+++
b/infra/url/core/src/test/java/org/apache/shardingsphere/infra/url/core/arg/URLArgumentLineTest.java
@@ -30,6 +30,10 @@ class URLArgumentLineTest {
private final String line = "key=$${value::default_value}";
+ private final String lineMultiple1 =
"key1=$${value1::default_value1}:key2=$${value2::default_value2}:tail";
+
+ private final String lineMultiple2 =
"key1=$${value1::}:key2=$${value2::}:tail";
+
@Test
void assertParseWithInvalidPattern() {
assertFalse(URLArgumentLine.parse("invalid").isPresent());
@@ -38,22 +42,42 @@ class URLArgumentLineTest {
@Test
void assertReplaceArgumentWithNone() {
Optional<URLArgumentLine> argLine = URLArgumentLine.parse(line);
+ Optional<URLArgumentLine> argLineMultiple1 =
URLArgumentLine.parse(lineMultiple1);
+ Optional<URLArgumentLine> argLineMultiple2 =
URLArgumentLine.parse(lineMultiple2);
assertTrue(argLine.isPresent());
+ assertTrue(argLineMultiple1.isPresent());
+ assertTrue(argLineMultiple2.isPresent());
assertThat(argLine.get().replaceArgument(URLArgumentPlaceholderType.NONE),
is("key=default_value"));
+
assertThat(argLineMultiple1.get().replaceArgument(URLArgumentPlaceholderType.NONE),
is("key1=default_value1:key2=default_value2:tail"));
+
assertThat(argLineMultiple2.get().replaceArgument(URLArgumentPlaceholderType.NONE),
is("key1=:key2=:tail"));
}
@Test
void assertReplaceArgumentWithEnvironment() {
Optional<URLArgumentLine> argLine = URLArgumentLine.parse(line);
+ Optional<URLArgumentLine> argLineMultiple1 =
URLArgumentLine.parse(lineMultiple1);
+ Optional<URLArgumentLine> argLineMultiple2 =
URLArgumentLine.parse(lineMultiple2);
assertTrue(argLine.isPresent());
+ assertTrue(argLineMultiple1.isPresent());
+ assertTrue(argLineMultiple2.isPresent());
assertThat(argLine.get().replaceArgument(URLArgumentPlaceholderType.ENVIRONMENT),
is("key=default_value"));
+
assertThat(argLineMultiple1.get().replaceArgument(URLArgumentPlaceholderType.ENVIRONMENT),
is("key1=default_value1:key2=default_value2:tail"));
+
assertThat(argLineMultiple2.get().replaceArgument(URLArgumentPlaceholderType.ENVIRONMENT),
is("key1=:key2=:tail"));
}
@Test
void assertReplaceArgumentWithSystemProperty() {
System.setProperty("value", "props_value");
+ System.setProperty("value1", "props_value1");
+ System.setProperty("value2", "props_value2");
Optional<URLArgumentLine> argLine = URLArgumentLine.parse(line);
+ Optional<URLArgumentLine> argLineMultiple1 =
URLArgumentLine.parse(lineMultiple1);
+ Optional<URLArgumentLine> argLineMultiple2 =
URLArgumentLine.parse(lineMultiple2);
assertTrue(argLine.isPresent());
+ assertTrue(argLineMultiple1.isPresent());
+ assertTrue(argLineMultiple2.isPresent());
assertThat(argLine.get().replaceArgument(URLArgumentPlaceholderType.SYSTEM_PROPS),
is("key=props_value"));
+
assertThat(argLineMultiple1.get().replaceArgument(URLArgumentPlaceholderType.SYSTEM_PROPS),
is("key1=props_value1:key2=props_value2:tail"));
+
assertThat(argLineMultiple2.get().replaceArgument(URLArgumentPlaceholderType.SYSTEM_PROPS),
is("key1=props_value1:key2=props_value2:tail"));
}
}