This is an automated email from the ASF dual-hosted git repository.
terrymanu 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 7a43b7fa4fa Fix insecure Bean Validation message templates (#40304)
7a43b7fa4fa is described below
commit 7a43b7fa4faebe14f49fa84e06a8c190daea4662
Author: Liang Zhang <[email protected]>
AuthorDate: Tue Oct 20 22:08:21 2026 +0800
Fix insecure Bean Validation message templates (#40304)
---
.../EncryptTableRuleConfigurationValidator.java | 8 +--
.../config/EncryptRuleConfigurationTest.java | 33 ++++++++---
.../mask/config/MaskRuleConfigurationTest.java | 9 ++-
.../ReadwriteSplittingRuleConfigurationTest.java | 3 +-
.../ShadowRuleConfigurationValidator.java | 14 ++---
.../shadow/config/ShadowRuleConfigurationTest.java | 19 +++++++
.../ShardingRuleConfigurationValidator.java | 19 +++----
.../ShardingTableRuleConfigurationValidator.java | 3 +-
.../api/config/ShardingRuleConfigurationTest.java | 64 ++++++++++++++--------
...hardingTableRuleConfigurationValidatorTest.java | 4 +-
.../reference/ConfigurationReferenceExists.java | 4 +-
.../ConfigurationReferenceExistsValidator.java | 5 +-
.../unique/UniqueTableNamesValidator.java | 2 +-
.../ConfigurationReferenceExistsValidatorTest.java | 16 ++++--
.../unique/UniqueTableNamesValidatorTest.java | 13 +++--
...YamlRuntimeDatabaseConfigurationsValidator.java | 46 ++++++++--------
.../YamlMCPLaunchConfigurationSwapperTest.java | 54 +++++++-----------
17 files changed, 177 insertions(+), 139 deletions(-)
diff --git
a/features/encrypt/api/src/main/java/org/apache/shardingsphere/encrypt/config/validator/EncryptTableRuleConfigurationValidator.java
b/features/encrypt/api/src/main/java/org/apache/shardingsphere/encrypt/config/validator/EncryptTableRuleConfigurationValidator.java
index ea8c69e2771..fbef3a83c83 100644
---
a/features/encrypt/api/src/main/java/org/apache/shardingsphere/encrypt/config/validator/EncryptTableRuleConfigurationValidator.java
+++
b/features/encrypt/api/src/main/java/org/apache/shardingsphere/encrypt/config/validator/EncryptTableRuleConfigurationValidator.java
@@ -44,18 +44,18 @@ public final class EncryptTableRuleConfigurationValidator
implements ConstraintV
private boolean isDerivedColumnValid(final EncryptColumnRuleConfiguration
columnConfig, final Collection<String> logicColumnNames, final
ConstraintValidatorContext context) {
Optional<EncryptColumnItemRuleConfiguration> assistedQuery =
columnConfig.getAssistedQuery();
if (assistedQuery.isPresent() &&
logicColumnNames.contains(assistedQuery.get().getName())) {
- return addConstraintViolation("assisted query",
assistedQuery.get().getName(), context);
+ return addConstraintViolation("assisted query column conflicts
with a logic column", context);
}
Optional<EncryptColumnItemRuleConfiguration> likeQuery =
columnConfig.getLikeQuery();
if (likeQuery.isPresent() &&
logicColumnNames.contains(likeQuery.get().getName())) {
- return addConstraintViolation("like query",
likeQuery.get().getName(), context);
+ return addConstraintViolation("like query column conflicts with a
logic column", context);
}
return true;
}
- private boolean addConstraintViolation(final String columnType, final
String columnName, final ConstraintValidatorContext context) {
+ private boolean addConstraintViolation(final String message, final
ConstraintValidatorContext context) {
context.disableDefaultConstraintViolation();
- context.buildConstraintViolationWithTemplate(String.format("%s column
`%s` conflicts with a logic column", columnType,
columnName)).addPropertyNode("columns").addConstraintViolation();
+
context.buildConstraintViolationWithTemplate(message).addPropertyNode("columns").addConstraintViolation();
return false;
}
}
diff --git
a/features/encrypt/api/src/test/java/org/apache/shardingsphere/encrypt/config/EncryptRuleConfigurationTest.java
b/features/encrypt/api/src/test/java/org/apache/shardingsphere/encrypt/config/EncryptRuleConfigurationTest.java
index 2d641e0811a..cdd35562421 100644
---
a/features/encrypt/api/src/test/java/org/apache/shardingsphere/encrypt/config/EncryptRuleConfigurationTest.java
+++
b/features/encrypt/api/src/test/java/org/apache/shardingsphere/encrypt/config/EncryptRuleConfigurationTest.java
@@ -116,15 +116,15 @@ class EncryptRuleConfigurationTest {
EncryptRuleConfiguration ruleConfig = createRuleConfiguration(new
EncryptColumnRuleConfiguration(
"foo_col", new
EncryptColumnItemRuleConfiguration("foo_cipher", "bar_encryptor")));
InvalidRuleConfigurationException actual =
assertThrows(InvalidRuleConfigurationException.class, () ->
RuleConfigurationValidator.validate(ruleConfig));
- assertThat(actual.getMessage(), is("Invalid 'EncryptRuleConfiguration'
rule, error message is: Property `tables` references unconfigured encryptors
`bar_encryptor`."));
+ assertThat(actual.getMessage(), is("Invalid 'EncryptRuleConfiguration'
rule, error message is: Property `tables` references unconfigured
encryptors."));
}
@Test
void assertDuplicateTableNamesViolation() {
- EncryptRuleConfiguration ruleConfig = new
EncryptRuleConfiguration(Arrays.asList(new
EncryptTableRuleConfiguration("foo_tbl", Collections.emptyList()),
- new EncryptTableRuleConfiguration("bar_tbl",
Collections.emptyList()), new EncryptTableRuleConfiguration("foo_tbl",
Collections.emptyList())), Collections.emptyMap());
+ EncryptRuleConfiguration ruleConfig = new
EncryptRuleConfiguration(Arrays.asList(new
EncryptTableRuleConfiguration("foo_{message}", Collections.emptyList()),
+ new EncryptTableRuleConfiguration("bar_tbl",
Collections.emptyList()), new EncryptTableRuleConfiguration("foo_{message}",
Collections.emptyList())), Collections.emptyMap());
InvalidRuleConfigurationException actual =
assertThrows(InvalidRuleConfigurationException.class, () ->
RuleConfigurationValidator.validate(ruleConfig));
- assertThat(actual.getMessage(), is("Invalid 'EncryptRuleConfiguration'
rule, error message is: Property `tables` must not contain duplicate table
names `foo_tbl`."));
+ assertThat(actual.getMessage(), is("Invalid 'EncryptRuleConfiguration'
rule, error message is: Property `tables` must not contain duplicate table
names."));
SQLException actualSQLException = actual.toSQLException();
assertThat(actualSQLException.getMessage(), is(actual.getMessage()));
assertThat(actualSQLException.getSQLState(), is("44000"));
@@ -194,13 +194,32 @@ class EncryptRuleConfigurationTest {
Arguments.of("Like query column conflicts with another logic
column",
createRuleConfiguration(Arrays.asList(crossColumnLikeQueryNameConflict,
otherLogicColumn), encryptors)));
}
+ @Test
+ void assertValidateAssistedQueryWithTemplateName() {
+ EncryptColumnRuleConfiguration columnConfig = new
EncryptColumnRuleConfiguration("foo_{message}", new
EncryptColumnItemRuleConfiguration("foo_cipher", "foo_encryptor"));
+ columnConfig.setAssistedQuery(new
EncryptColumnItemRuleConfiguration("foo_{message}", "foo_encryptor"));
+ EncryptRuleConfiguration ruleConfig =
createRuleConfiguration(columnConfig, Collections.singletonMap("foo_encryptor",
new AlgorithmConfiguration("FIXTURE", new Properties())));
+ InvalidRuleConfigurationException actual =
assertThrows(InvalidRuleConfigurationException.class, () ->
RuleConfigurationValidator.validate(ruleConfig));
+ assertThat(actual.getMessage(), is("Invalid 'EncryptRuleConfiguration'
rule, error message is: Property `tables[].columns` assisted query column
conflicts with a logic column."));
+ }
+
+ @Test
+ void assertValidateLikeQueryWithTemplateName() {
+ EncryptColumnRuleConfiguration columnConfig = new
EncryptColumnRuleConfiguration("foo_{message}", new
EncryptColumnItemRuleConfiguration("foo_cipher", "foo_encryptor"));
+ columnConfig.setLikeQuery(new
EncryptColumnItemRuleConfiguration("foo_{message}", "foo_encryptor"));
+ EncryptRuleConfiguration ruleConfig =
createRuleConfiguration(columnConfig, Collections.singletonMap("foo_encryptor",
new AlgorithmConfiguration("FIXTURE", new Properties())));
+ InvalidRuleConfigurationException actual =
assertThrows(InvalidRuleConfigurationException.class, () ->
RuleConfigurationValidator.validate(ruleConfig));
+ assertThat(actual.getMessage(), is("Invalid 'EncryptRuleConfiguration'
rule, error message is: Property `tables[].columns` like query column conflicts
with a logic column."));
+ }
+
@Test
void assertValidateInvalidRuleItemConfiguration() {
- EncryptColumnRuleConfiguration columnConfig =
createValidColumnConfiguration();
- columnConfig.setAssistedQuery(new
EncryptColumnItemRuleConfiguration("foo_col", "foo_encryptor"));
+ EncryptColumnRuleConfiguration columnConfig = new
EncryptColumnRuleConfiguration("foo_{message}", new
EncryptColumnItemRuleConfiguration("foo_cipher", "foo_encryptor"));
+ columnConfig.setAssistedQuery(new
EncryptColumnItemRuleConfiguration("foo_{message}", "foo_encryptor"));
EncryptTableRuleConfiguration tableConfig = new
EncryptTableRuleConfiguration("foo_tbl", Collections.singleton(columnConfig));
EncryptRuleConfiguration ruleConfig = new
EncryptRuleConfiguration(Collections.emptyList(), Collections.emptyMap());
- assertThrows(InvalidRuleConfigurationException.class, () ->
RuleConfigurationValidator.validateRuleItem(ruleConfig, tableConfig));
+ InvalidRuleConfigurationException actual =
assertThrows(InvalidRuleConfigurationException.class, () ->
RuleConfigurationValidator.validateRuleItem(ruleConfig, tableConfig));
+ assertThat(actual.getMessage(), is("Invalid 'EncryptRuleConfiguration'
rule, error message is: Property `columns` assisted query column conflicts with
a logic column."));
}
private static EncryptColumnRuleConfiguration
createValidColumnConfiguration() {
diff --git
a/features/mask/api/src/test/java/org/apache/shardingsphere/mask/config/MaskRuleConfigurationTest.java
b/features/mask/api/src/test/java/org/apache/shardingsphere/mask/config/MaskRuleConfigurationTest.java
index 7ab22f97410..a441a81c126 100644
---
a/features/mask/api/src/test/java/org/apache/shardingsphere/mask/config/MaskRuleConfigurationTest.java
+++
b/features/mask/api/src/test/java/org/apache/shardingsphere/mask/config/MaskRuleConfigurationTest.java
@@ -35,7 +35,6 @@ import java.util.Properties;
import java.util.stream.Stream;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -98,7 +97,7 @@ class MaskRuleConfigurationTest {
void assertUnconfiguredMaskAlgorithmViolation() {
MaskRuleConfiguration ruleConfig = createRuleConfiguration(new
MaskColumnRuleConfiguration("foo_col", "bar_mask"));
InvalidRuleConfigurationException actual =
assertThrows(InvalidRuleConfigurationException.class, () ->
RuleConfigurationValidator.validate(ruleConfig));
- assertThat(actual.getMessage(), containsString("Property `tables`
references unconfigured maskAlgorithms `bar_mask`."));
+ assertThat(actual.getMessage(), is("Invalid 'MaskRuleConfiguration'
rule, error message is: Property `tables` references unconfigured
maskAlgorithms."));
}
@Test
@@ -107,7 +106,7 @@ class MaskRuleConfigurationTest {
new MaskTableRuleConfiguration("bar_tbl",
Collections.emptyList()), new MaskTableRuleConfiguration("foo_tbl",
Collections.emptyList()),
new MaskTableRuleConfiguration("bar_tbl",
Collections.emptyList()), new MaskTableRuleConfiguration("foo_tbl",
Collections.emptyList())), Collections.emptyMap());
InvalidRuleConfigurationException actual =
assertThrows(InvalidRuleConfigurationException.class, () ->
RuleConfigurationValidator.validate(ruleConfig));
- assertThat(actual.getMessage(), is("Invalid 'MaskRuleConfiguration'
rule, error message is: Property `tables` must not contain duplicate table
names `foo_tbl, bar_tbl`."));
+ assertThat(actual.getMessage(), is("Invalid 'MaskRuleConfiguration'
rule, error message is: Property `tables` must not contain duplicate table
names."));
SQLException actualSQLException = actual.toSQLException();
assertThat(actualSQLException.getMessage(), is(actual.getMessage()));
assertThat(actualSQLException.getSQLState(), is("44000"));
@@ -120,8 +119,8 @@ class MaskRuleConfigurationTest {
new MaskTableRuleConfiguration("foo_tbl",
Collections.singleton(new MaskColumnRuleConfiguration("foo_col", "bar_mask"))),
new MaskTableRuleConfiguration("foo_tbl",
Collections.emptyList())), Collections.emptyMap());
InvalidRuleConfigurationException actual =
assertThrows(InvalidRuleConfigurationException.class, () ->
RuleConfigurationValidator.validate(ruleConfig));
- assertThat(actual.getMessage(), is("Invalid 'MaskRuleConfiguration'
rule, error message is: Property `tables` must not contain duplicate table
names `foo_tbl`.; "
- + "Property `tables` references unconfigured maskAlgorithms
`bar_mask`."));
+ assertThat(actual.getMessage(), is("Invalid 'MaskRuleConfiguration'
rule, error message is: Property `tables` must not contain duplicate table
names.; "
+ + "Property `tables` references unconfigured
maskAlgorithms."));
}
private static Stream<Arguments> invalidRuleConfigurationArguments() {
diff --git
a/features/readwrite-splitting/api/src/test/java/org/apache/shardingsphere/readwritesplitting/config/ReadwriteSplittingRuleConfigurationTest.java
b/features/readwrite-splitting/api/src/test/java/org/apache/shardingsphere/readwritesplitting/config/ReadwriteSplittingRuleConfigurationTest.java
index feb67831433..d68b98e298a 100644
---
a/features/readwrite-splitting/api/src/test/java/org/apache/shardingsphere/readwritesplitting/config/ReadwriteSplittingRuleConfigurationTest.java
+++
b/features/readwrite-splitting/api/src/test/java/org/apache/shardingsphere/readwritesplitting/config/ReadwriteSplittingRuleConfigurationTest.java
@@ -87,8 +87,7 @@ class ReadwriteSplittingRuleConfigurationTest {
ReadwriteSplittingRuleConfiguration ruleConfig =
createRuleConfiguration(new ReadwriteSplittingDataSourceGroupRuleConfiguration(
"foo_group", "foo_write",
Collections.singletonList("foo_read"), "bar_load_balancer"));
InvalidRuleConfigurationException actual =
assertThrows(InvalidRuleConfigurationException.class, () ->
RuleConfigurationValidator.validate(ruleConfig));
- assertThat(actual.getMessage(),
- is("Invalid 'ReadwriteSplittingRuleConfiguration' rule, error
message is: Property `dataSourceGroups` references unconfigured loadBalancers
`bar_load_balancer`."));
+ assertThat(actual.getMessage(), is("Invalid
'ReadwriteSplittingRuleConfiguration' rule, error message is: Property
`dataSourceGroups` references unconfigured loadBalancers."));
}
private static Stream<Arguments> invalidRuleConfigurationArguments() {
diff --git
a/features/shadow/api/src/main/java/org/apache/shardingsphere/shadow/config/validator/ShadowRuleConfigurationValidator.java
b/features/shadow/api/src/main/java/org/apache/shardingsphere/shadow/config/validator/ShadowRuleConfigurationValidator.java
index a640e91b2ef..10dd94dc8d8 100644
---
a/features/shadow/api/src/main/java/org/apache/shardingsphere/shadow/config/validator/ShadowRuleConfigurationValidator.java
+++
b/features/shadow/api/src/main/java/org/apache/shardingsphere/shadow/config/validator/ShadowRuleConfigurationValidator.java
@@ -52,15 +52,14 @@ public final class ShadowRuleConfigurationValidator
implements ConstraintValidat
private boolean areTableDataSourcesValid(final ShadowRuleConfiguration
ruleConfig, final ConstraintValidatorContext context) {
Collection<String> dataSourceNames =
ruleConfig.getDataSources().stream().map(ShadowDataSourceConfiguration::getName).collect(Collectors.toSet());
- return ruleConfig.getTables().entrySet().stream().allMatch(entry ->
areTableDataSourcesValid(entry.getKey(), entry.getValue(), dataSourceNames,
context));
+ return ruleConfig.getTables().values().stream().allMatch(each ->
areTableDataSourcesValid(each, dataSourceNames, context));
}
- private boolean areTableDataSourcesValid(final String tableName, final
ShadowTableConfiguration tableConfig, final Collection<String> dataSourceNames,
final ConstraintValidatorContext context) {
+ private boolean areTableDataSourcesValid(final ShadowTableConfiguration
tableConfig, final Collection<String> dataSourceNames, final
ConstraintValidatorContext context) {
for (String each : tableConfig.getDataSourceNames()) {
if (!dataSourceNames.contains(each)) {
context.disableDefaultConstraintViolation();
-
context.buildConstraintViolationWithTemplate(String.format("table `%s`
references unconfigured shadow data source `%s`", tableName, each))
- .addPropertyNode("tables").addConstraintViolation();
+ context.buildConstraintViolationWithTemplate("references an
unconfigured shadow data
source").addPropertyNode("tables").addConstraintViolation();
return false;
}
}
@@ -68,15 +67,14 @@ public final class ShadowRuleConfigurationValidator
implements ConstraintValidat
}
private boolean areTableAlgorithmsValid(final ShadowRuleConfiguration
ruleConfig, final ConstraintValidatorContext context) {
- return ruleConfig.getTables().entrySet().stream().allMatch(entry ->
areTableAlgorithmsValid(entry.getKey(), entry.getValue(), ruleConfig, context));
+ return ruleConfig.getTables().values().stream().allMatch(each ->
areTableAlgorithmsValid(each, ruleConfig, context));
}
- private boolean areTableAlgorithmsValid(final String tableName, final
ShadowTableConfiguration tableConfig, final ShadowRuleConfiguration ruleConfig,
final ConstraintValidatorContext context) {
+ private boolean areTableAlgorithmsValid(final ShadowTableConfiguration
tableConfig, final ShadowRuleConfiguration ruleConfig, final
ConstraintValidatorContext context) {
for (String each : tableConfig.getShadowAlgorithmNames()) {
if (!ruleConfig.getShadowAlgorithms().containsKey(each)) {
context.disableDefaultConstraintViolation();
-
context.buildConstraintViolationWithTemplate(String.format("table `%s`
references unconfigured shadow algorithm `%s`", tableName, each))
- .addPropertyNode("tables").addConstraintViolation();
+ context.buildConstraintViolationWithTemplate("references an
unconfigured shadow
algorithm").addPropertyNode("tables").addConstraintViolation();
return false;
}
}
diff --git
a/features/shadow/api/src/test/java/org/apache/shardingsphere/shadow/config/ShadowRuleConfigurationTest.java
b/features/shadow/api/src/test/java/org/apache/shardingsphere/shadow/config/ShadowRuleConfigurationTest.java
index 1fedec45649..948bd1662d9 100644
---
a/features/shadow/api/src/test/java/org/apache/shardingsphere/shadow/config/ShadowRuleConfigurationTest.java
+++
b/features/shadow/api/src/test/java/org/apache/shardingsphere/shadow/config/ShadowRuleConfigurationTest.java
@@ -22,6 +22,7 @@ import
org.apache.shardingsphere.infra.config.rule.validator.RuleConfigurationVa
import
org.apache.shardingsphere.infra.exception.kernel.metadata.rule.InvalidRuleConfigurationException;
import
org.apache.shardingsphere.shadow.config.datasource.ShadowDataSourceConfiguration;
import org.apache.shardingsphere.shadow.config.table.ShadowTableConfiguration;
+import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
@@ -89,6 +90,24 @@ class ShadowRuleConfigurationTest {
Arguments.of("Whitespace shadow algorithm type reaches SPI", "
", "Property `shadowAlgorithms` does not match an available SPI
implementation."));
}
+ @Test
+ void assertValidateUnconfiguredDataSourceWithTemplateNames() {
+ ShadowRuleConfiguration ruleConfig =
createRuleConfiguration(Collections.singleton(new
ShadowDataSourceConfiguration("foo_ds", "foo_primary", "foo_shadow")),
+ Collections.singletonMap("foo_{message}", new
ShadowTableConfiguration(Collections.singleton("bar_{message}"),
Collections.singleton("foo_shadow_algorithm"))),
+ Collections.singletonMap("foo_shadow_algorithm", new
AlgorithmConfiguration("FIXTURE", new Properties())));
+ InvalidRuleConfigurationException actual =
assertThrows(InvalidRuleConfigurationException.class, () ->
RuleConfigurationValidator.validate(ruleConfig));
+ assertThat(actual.getMessage(), is("Invalid 'ShadowRuleConfiguration'
rule, error message is: Property `tables` references an unconfigured shadow
data source."));
+ }
+
+ @Test
+ void assertValidateUnconfiguredAlgorithmWithTemplateNames() {
+ ShadowRuleConfiguration ruleConfig =
createRuleConfiguration(Collections.singleton(new
ShadowDataSourceConfiguration("foo_ds", "foo_primary", "foo_shadow")),
+ Collections.singletonMap("foo_{message}", new
ShadowTableConfiguration(Collections.singleton("foo_ds"),
Collections.singleton("bar_{message}"))),
+ Collections.singletonMap("foo_shadow_algorithm", new
AlgorithmConfiguration("FIXTURE", new Properties())));
+ InvalidRuleConfigurationException actual =
assertThrows(InvalidRuleConfigurationException.class, () ->
RuleConfigurationValidator.validate(ruleConfig));
+ assertThat(actual.getMessage(), is("Invalid 'ShadowRuleConfiguration'
rule, error message is: Property `tables` references an unconfigured shadow
algorithm."));
+ }
+
@ParameterizedTest(name = "{0}")
@MethodSource("invalidRuleConfigurationArguments")
void assertValidateInvalidRuleConfiguration(final String name, final
ShadowRuleConfiguration ruleConfig) {
diff --git
a/features/sharding/api/src/main/java/org/apache/shardingsphere/sharding/api/config/validator/ShardingRuleConfigurationValidator.java
b/features/sharding/api/src/main/java/org/apache/shardingsphere/sharding/api/config/validator/ShardingRuleConfigurationValidator.java
index 11369ea92c7..9882ec99196 100644
---
a/features/sharding/api/src/main/java/org/apache/shardingsphere/sharding/api/config/validator/ShardingRuleConfigurationValidator.java
+++
b/features/sharding/api/src/main/java/org/apache/shardingsphere/sharding/api/config/validator/ShardingRuleConfigurationValidator.java
@@ -65,21 +65,19 @@ public final class ShardingRuleConfigurationValidator
implements ConstraintValid
if (null == strategyConfig ||
ruleConfig.getKeyGenerators().containsKey(strategyConfig.getKeyGeneratorName()))
{
return true;
}
- return addViolation(propertyName, String.format("references
unconfigured key generator `%s`", strategyConfig.getKeyGeneratorName()),
context);
+ return addViolation(propertyName, "references an unconfigured key
generator", context);
}
private boolean areKeyGenerateStrategiesValid(final
ShardingRuleConfiguration ruleConfig, final ConstraintValidatorContext context)
{
- return
ruleConfig.getKeyGenerateStrategies().entrySet().stream().allMatch(entry ->
isKeyGenerateStrategiesValid(entry.getKey(), entry.getValue(), ruleConfig,
context));
+ return
ruleConfig.getKeyGenerateStrategies().values().stream().allMatch(each ->
isKeyGenerateStrategiesValid(each, ruleConfig, context));
}
- private boolean isKeyGenerateStrategiesValid(final String strategyName,
final KeyGenerateStrategiesConfiguration strategyConfig,
- final
ShardingRuleConfiguration ruleConfig, final ConstraintValidatorContext context)
{
+ private boolean isKeyGenerateStrategiesValid(final
KeyGenerateStrategiesConfiguration strategyConfig, final
ShardingRuleConfiguration ruleConfig, final ConstraintValidatorContext context)
{
if (!(strategyConfig instanceof
ColumnKeyGenerateStrategiesRuleConfiguration) && !(strategyConfig instanceof
SequenceKeyGenerateStrategiesRuleConfiguration)) {
- return addViolation("keyGenerateStrategies",
String.format("strategy `%s` must use column or sequence key generation",
strategyName), context);
+ return addViolation("keyGenerateStrategies", "must use column or
sequence key generation", context);
}
if
(!ruleConfig.getKeyGenerators().containsKey(strategyConfig.getKeyGeneratorName()))
{
- return addViolation("keyGenerateStrategies",
String.format("strategy `%s` references unconfigured key generator `%s`",
- strategyName, strategyConfig.getKeyGeneratorName()),
context);
+ return addViolation("keyGenerateStrategies", "references an
unconfigured key generator", context);
}
return true;
}
@@ -89,9 +87,8 @@ public final class ShardingRuleConfigurationValidator
implements ConstraintValid
if (null == strategyConfig) {
return true;
}
- return strategyConfig.getAuditorNames().stream()
- .filter(each ->
!ruleConfig.getAuditors().containsKey(each)).findFirst()
- .map(each -> addViolation(propertyName,
String.format("references unconfigured auditor `%s`", each),
context)).orElse(true);
+ return strategyConfig.getAuditorNames().stream().filter(each ->
!ruleConfig.getAuditors().containsKey(each)).findFirst()
+ .map(optional -> addViolation(propertyName, "references an
unconfigured auditor", context)).orElse(true);
}
private boolean isShardingStrategyValid(final
ShardingStrategyConfiguration strategyConfig, final String propertyName,
@@ -99,7 +96,7 @@ public final class ShardingRuleConfigurationValidator
implements ConstraintValid
if (null == strategyConfig || strategyConfig instanceof
NoneShardingStrategyConfiguration ||
ruleConfig.getShardingAlgorithms().containsKey(strategyConfig.getShardingAlgorithmName()))
{
return true;
}
- return addViolation(propertyName, String.format("references
unconfigured sharding algorithm `%s`",
strategyConfig.getShardingAlgorithmName()), context);
+ return addViolation(propertyName, "references an unconfigured sharding
algorithm", context);
}
private boolean addViolation(final String propertyName, final String
message, final ConstraintValidatorContext context) {
diff --git
a/features/sharding/api/src/main/java/org/apache/shardingsphere/sharding/api/config/validator/ShardingTableRuleConfigurationValidator.java
b/features/sharding/api/src/main/java/org/apache/shardingsphere/sharding/api/config/validator/ShardingTableRuleConfigurationValidator.java
index 12740d73ab7..943f980f381 100644
---
a/features/sharding/api/src/main/java/org/apache/shardingsphere/sharding/api/config/validator/ShardingTableRuleConfigurationValidator.java
+++
b/features/sharding/api/src/main/java/org/apache/shardingsphere/sharding/api/config/validator/ShardingTableRuleConfigurationValidator.java
@@ -44,8 +44,7 @@ public final class ShardingTableRuleConfigurationValidator
implements Constraint
String configuredSchemaName =
schemaNamesByDataSource.putIfAbsent(dataNode.getDataSourceName(),
dataNode.getSchemaName());
if (null != configuredSchemaName &&
!configuredSchemaName.equalsIgnoreCase(dataNode.getSchemaName())) {
context.disableDefaultConstraintViolation();
-
context.buildConstraintViolationWithTemplate(String.format("contains multiple
schemas for storage unit `%s` in sharding table `%s`",
- dataNode.getDataSourceName(),
value.getLogicTable())).addPropertyNode("actualDataNodes").addConstraintViolation();
+
context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate()).addPropertyNode("actualDataNodes").addConstraintViolation();
return false;
}
}
diff --git
a/features/sharding/api/src/test/java/org/apache/shardingsphere/sharding/api/config/ShardingRuleConfigurationTest.java
b/features/sharding/api/src/test/java/org/apache/shardingsphere/sharding/api/config/ShardingRuleConfigurationTest.java
index 3cf2c7710b8..36e48ccc04f 100644
---
a/features/sharding/api/src/test/java/org/apache/shardingsphere/sharding/api/config/ShardingRuleConfigurationTest.java
+++
b/features/sharding/api/src/test/java/org/apache/shardingsphere/sharding/api/config/ShardingRuleConfigurationTest.java
@@ -75,8 +75,7 @@ class ShardingRuleConfigurationTest {
void assertValidateMultipleSchemasForSameDataSource() {
ShardingRuleConfiguration ruleConfig = createRuleConfiguration(new
ShardingTableRuleConfiguration("foo_tbl",
"ds_0.foo_schema_${0..1}.foo_tbl_${0..1}"));
InvalidRuleConfigurationException actual =
assertThrows(InvalidRuleConfigurationException.class, () ->
RuleConfigurationValidator.validate(ruleConfig));
- assertThat(actual.getMessage(), is("Invalid
'ShardingRuleConfiguration' rule, error message is: "
- + "Property `tables[0].actualDataNodes` contains multiple
schemas for storage unit `ds_0` in sharding table `foo_tbl`."));
+ assertThat(actual.getMessage(), is("Invalid
'ShardingRuleConfiguration' rule, error message is: Property
`tables[0].actualDataNodes` contains multiple schemas for a storage unit."));
}
@Test
@@ -84,11 +83,26 @@ class ShardingRuleConfigurationTest {
ShardingRuleConfiguration ruleConfig = new ShardingRuleConfiguration();
ShardingTableRuleConfiguration tableConfig = new
ShardingTableRuleConfiguration("foo_tbl",
"ds_0.foo_schema_${0..1}.foo_tbl_${0..1}");
InvalidRuleConfigurationException actual =
assertThrows(InvalidRuleConfigurationException.class, () ->
RuleConfigurationValidator.validateRuleItem(ruleConfig, tableConfig));
- assertThat(actual.getMessage(), is("Invalid
'ShardingRuleConfiguration' rule, error message is: "
- + "Property `actualDataNodes` contains multiple schemas for
storage unit `ds_0` in sharding table `foo_tbl`."));
+ assertThat(actual.getMessage(), is("Invalid
'ShardingRuleConfiguration' rule, error message is: Property `actualDataNodes`
contains multiple schemas for a storage unit."));
assertTrue(ruleConfig.getTables().isEmpty());
}
+ @Test
+ void assertValidateWithTemplateNames() {
+ ShardingRuleConfiguration ruleConfig = createRuleConfiguration(
+ new ShardingTableRuleConfiguration("foo_{message}",
"<LITERAL>ds_{message}.foo_schema.foo_tbl_0,ds_{message}.bar_schema.foo_tbl_1"));
+ InvalidRuleConfigurationException actual =
assertThrows(InvalidRuleConfigurationException.class, () ->
RuleConfigurationValidator.validate(ruleConfig));
+ assertThat(actual.getMessage(), is("Invalid
'ShardingRuleConfiguration' rule, error message is: Property
`tables[0].actualDataNodes` contains multiple schemas for a storage unit."));
+ }
+
+ @Test
+ void assertValidateRuleItemWithTemplateNames() {
+ ShardingTableRuleConfiguration tableConfig = new
ShardingTableRuleConfiguration("foo_{message}",
"<LITERAL>ds_{message}.foo_schema.foo_tbl_0,ds_{message}.bar_schema.foo_tbl_1");
+ InvalidRuleConfigurationException actual =
assertThrows(InvalidRuleConfigurationException.class,
+ () -> RuleConfigurationValidator.validateRuleItem(new
ShardingRuleConfiguration(), tableConfig));
+ assertThat(actual.getMessage(), is("Invalid
'ShardingRuleConfiguration' rule, error message is: Property `actualDataNodes`
contains multiple schemas for a storage unit."));
+ }
+
@ParameterizedTest(name = "{0}")
@MethodSource("validSchemaDataNodesArguments")
void assertValidateValidSchemaDataNodes(final String name, final
ShardingTableRuleConfiguration tableConfig) {
@@ -332,14 +346,14 @@ class ShardingRuleConfigurationTest {
@ParameterizedTest(name = "{0}")
@MethodSource("invalidReferenceRuleConfigurationArguments")
- void assertValidateInvalidReferenceRuleConfiguration(final String name,
final ShardingRuleConfiguration ruleConfig) {
- assertThrows(InvalidRuleConfigurationException.class, () ->
RuleConfigurationValidator.validate(ruleConfig));
+ void assertValidateInvalidReferenceRuleConfiguration(final String name,
final ShardingRuleConfiguration ruleConfig, final String expectedMessage) {
+ InvalidRuleConfigurationException actual =
assertThrows(InvalidRuleConfigurationException.class, () ->
RuleConfigurationValidator.validate(ruleConfig));
+ assertThat(actual.getMessage(), is("Invalid
'ShardingRuleConfiguration' rule, error message is: " + expectedMessage));
}
private static Stream<Arguments>
invalidReferenceRuleConfigurationArguments() {
ShardingRuleConfiguration unconfiguredTableDatabaseShardingAlgorithm =
createValidRuleConfiguration();
-
unconfiguredTableDatabaseShardingAlgorithm.getTables().iterator().next()
- .setDatabaseShardingStrategy(new
StandardShardingStrategyConfiguration("user_id", "bar_standard"));
+
unconfiguredTableDatabaseShardingAlgorithm.getTables().iterator().next().setDatabaseShardingStrategy(new
StandardShardingStrategyConfiguration("user_id", "foo_{message}"));
ShardingRuleConfiguration unconfiguredTableShardingAlgorithm =
createValidRuleConfiguration();
unconfiguredTableShardingAlgorithm.getTables().iterator().next()
.setTableShardingStrategy(new
ComplexShardingStrategyConfiguration("order_id,user_id", "bar_complex"));
@@ -350,30 +364,32 @@ class ShardingRuleConfigurationTest {
ShardingRuleConfiguration unconfiguredDefaultTableShardingAlgorithm =
createValidRuleConfiguration();
unconfiguredDefaultTableShardingAlgorithm.setDefaultTableShardingStrategy(new
ComplexShardingStrategyConfiguration("order_id,user_id", "bar_complex"));
ShardingRuleConfiguration unconfiguredTableAuditor =
createValidRuleConfiguration();
-
unconfiguredTableAuditor.getTables().iterator().next().setAuditStrategy(new
ShardingAuditStrategyConfiguration(Collections.singleton("bar_auditor"),
false));
+
unconfiguredTableAuditor.getTables().iterator().next().setAuditStrategy(new
ShardingAuditStrategyConfiguration(Collections.singleton("foo_{message}"),
false));
ShardingRuleConfiguration unconfiguredAutoTableAuditor =
createValidRuleConfiguration();
unconfiguredAutoTableAuditor.getAutoTables().iterator().next().setAuditStrategy(new
ShardingAuditStrategyConfiguration(Collections.singleton("bar_auditor"),
false));
ShardingRuleConfiguration unconfiguredDefaultAuditor =
createValidRuleConfiguration();
unconfiguredDefaultAuditor.setDefaultAuditStrategy(new
ShardingAuditStrategyConfiguration(Collections.singleton("bar_auditor"),
false));
ShardingRuleConfiguration unconfiguredDefaultKeyGenerator =
createValidRuleConfiguration();
- unconfiguredDefaultKeyGenerator.setDefaultKeyGenerateStrategy(new
KeyGenerateStrategyConfiguration("order_id", "bar_key_generator"));
+ unconfiguredDefaultKeyGenerator.setDefaultKeyGenerateStrategy(new
KeyGenerateStrategyConfiguration("order_id", "foo_{message}"));
ShardingRuleConfiguration
unconfiguredKeyGenerateStrategiesKeyGenerator = createValidRuleConfiguration();
-
unconfiguredKeyGenerateStrategiesKeyGenerator.getKeyGenerateStrategies().put(
- "bar_column", new
ColumnKeyGenerateStrategiesRuleConfiguration("bar_key_generator", "foo_tbl",
"order_id"));
+
unconfiguredKeyGenerateStrategiesKeyGenerator.getKeyGenerateStrategies().put("foo_{message}",
new ColumnKeyGenerateStrategiesRuleConfiguration("bar_{message}", "foo_tbl",
"order_id"));
ShardingRuleConfiguration unsupportedKeyGenerateStrategies =
createValidRuleConfiguration();
-
unsupportedKeyGenerateStrategies.getKeyGenerateStrategies().put("bar_strategy",
new UnsupportedKeyGenerateStrategiesConfiguration());
+
unsupportedKeyGenerateStrategies.getKeyGenerateStrategies().put("foo_{message}",
new UnsupportedKeyGenerateStrategiesConfiguration());
return Stream.of(
- Arguments.of("Unconfigured table database sharding algorithm",
unconfiguredTableDatabaseShardingAlgorithm),
- Arguments.of("Unconfigured table sharding algorithm",
unconfiguredTableShardingAlgorithm),
- Arguments.of("Unconfigured auto table sharding algorithm",
unconfiguredAutoTableShardingAlgorithm),
- Arguments.of("Unconfigured default database sharding
algorithm", unconfiguredDefaultDatabaseShardingAlgorithm),
- Arguments.of("Unconfigured default table sharding algorithm",
unconfiguredDefaultTableShardingAlgorithm),
- Arguments.of("Unconfigured table auditor",
unconfiguredTableAuditor),
- Arguments.of("Unconfigured auto table auditor",
unconfiguredAutoTableAuditor),
- Arguments.of("Unconfigured default auditor",
unconfiguredDefaultAuditor),
- Arguments.of("Unconfigured default key generator",
unconfiguredDefaultKeyGenerator),
- Arguments.of("Unconfigured key generate strategies key
generator", unconfiguredKeyGenerateStrategiesKeyGenerator),
- Arguments.of("Unsupported key generate strategies type",
unsupportedKeyGenerateStrategies));
+ Arguments.of("Unconfigured table database sharding algorithm",
unconfiguredTableDatabaseShardingAlgorithm, "Property `tables` references an
unconfigured sharding algorithm."),
+ Arguments.of("Unconfigured table sharding algorithm",
unconfiguredTableShardingAlgorithm, "Property `tables` references an
unconfigured sharding algorithm."),
+ Arguments.of("Unconfigured auto table sharding algorithm",
unconfiguredAutoTableShardingAlgorithm, "Property `autoTables` references an
unconfigured sharding algorithm."),
+ Arguments.of("Unconfigured default database sharding
algorithm", unconfiguredDefaultDatabaseShardingAlgorithm,
+ "Property `defaultDatabaseShardingStrategy` references
an unconfigured sharding algorithm."),
+ Arguments.of("Unconfigured default table sharding algorithm",
unconfiguredDefaultTableShardingAlgorithm,
+ "Property `defaultTableShardingStrategy` references an
unconfigured sharding algorithm."),
+ Arguments.of("Unconfigured table auditor",
unconfiguredTableAuditor, "Property `tables` references an unconfigured
auditor."),
+ Arguments.of("Unconfigured auto table auditor",
unconfiguredAutoTableAuditor, "Property `autoTables` references an unconfigured
auditor."),
+ Arguments.of("Unconfigured default auditor",
unconfiguredDefaultAuditor, "Property `defaultAuditStrategy` references an
unconfigured auditor."),
+ Arguments.of("Unconfigured default key generator",
unconfiguredDefaultKeyGenerator, "Property `defaultKeyGenerateStrategy`
references an unconfigured key generator."),
+ Arguments.of("Unconfigured key generate strategies key
generator", unconfiguredKeyGenerateStrategiesKeyGenerator,
+ "Property `keyGenerateStrategies` references an
unconfigured key generator."),
+ Arguments.of("Unsupported key generate strategies type",
unsupportedKeyGenerateStrategies, "Property `keyGenerateStrategies` must use
column or sequence key generation."));
}
private static ShardingAutoTableRuleConfiguration
createValidAutoTableRuleConfiguration() {
diff --git
a/features/sharding/api/src/test/java/org/apache/shardingsphere/sharding/api/config/validator/ShardingTableRuleConfigurationValidatorTest.java
b/features/sharding/api/src/test/java/org/apache/shardingsphere/sharding/api/config/validator/ShardingTableRuleConfigurationValidatorTest.java
index ecdd2a71668..cdc90d2885e 100644
---
a/features/sharding/api/src/test/java/org/apache/shardingsphere/sharding/api/config/validator/ShardingTableRuleConfigurationValidatorTest.java
+++
b/features/sharding/api/src/test/java/org/apache/shardingsphere/sharding/api/config/validator/ShardingTableRuleConfigurationValidatorTest.java
@@ -82,10 +82,10 @@ class ShardingTableRuleConfigurationValidatorTest {
try (MockedStatic<InlineExpressionParserFactory> mockedFactory =
mockStatic(InlineExpressionParserFactory.class)) {
mockedFactory.when(() ->
InlineExpressionParserFactory.newInstance("data_nodes")).thenReturn(parser);
when(parser.splitAndEvaluate()).thenReturn(Arrays.asList("ds_0.foo_schema.foo_tbl_0",
"ds_0.bar_schema.foo_tbl_1"));
+
when(context.getDefaultConstraintMessageTemplate()).thenReturn("contains
multiple schemas for a storage unit");
assertFalse(validator.isValid(new
ShardingTableRuleConfiguration("foo_tbl", "data_nodes"), context));
verify(context).disableDefaultConstraintViolation();
- verify(context.buildConstraintViolationWithTemplate("contains
multiple schemas for storage unit `ds_0` in sharding table `foo_tbl`")
-
.addPropertyNode("actualDataNodes")).addConstraintViolation();
+ verify(context.buildConstraintViolationWithTemplate("contains
multiple schemas for a storage
unit").addPropertyNode("actualDataNodes")).addConstraintViolation();
}
}
}
diff --git
a/infra/common/src/main/java/org/apache/shardingsphere/infra/config/rule/validator/constraint/reference/ConfigurationReferenceExists.java
b/infra/common/src/main/java/org/apache/shardingsphere/infra/config/rule/validator/constraint/reference/ConfigurationReferenceExists.java
index 82cd7bd5ca0..73a74c07802 100644
---
a/infra/common/src/main/java/org/apache/shardingsphere/infra/config/rule/validator/constraint/reference/ConfigurationReferenceExists.java
+++
b/infra/common/src/main/java/org/apache/shardingsphere/infra/config/rule/validator/constraint/reference/ConfigurationReferenceExists.java
@@ -57,11 +57,11 @@ public @interface ConfigurationReferenceExists {
boolean allowEmpty() default false;
/**
- * Get the violation message. Use {pool} for the configuration pool
property and {reference} for the missing name.
+ * Get the violation message. Use {pool} for the configuration pool
property.
*
* @return violation message
*/
- String message() default "references unconfigured {pool} `{reference}`";
+ String message() default "references unconfigured {pool}";
/**
* Get groups.
diff --git
a/infra/common/src/main/java/org/apache/shardingsphere/infra/config/rule/validator/constraint/reference/ConfigurationReferenceExistsValidator.java
b/infra/common/src/main/java/org/apache/shardingsphere/infra/config/rule/validator/constraint/reference/ConfigurationReferenceExistsValidator.java
index 75c464e1567..ca6da035409 100644
---
a/infra/common/src/main/java/org/apache/shardingsphere/infra/config/rule/validator/constraint/reference/ConfigurationReferenceExistsValidator.java
+++
b/infra/common/src/main/java/org/apache/shardingsphere/infra/config/rule/validator/constraint/reference/ConfigurationReferenceExistsValidator.java
@@ -40,8 +40,6 @@ public final class ConfigurationReferenceExistsValidator
implements ConstraintVa
private boolean allowEmpty;
- private String message;
-
@Override
public void initialize(final ConfigurationReferenceExists
constraintAnnotation) {
ShardingSpherePreconditions.checkState(0 !=
constraintAnnotation.referencePaths().length, () -> new ValidationException("At
least one configuration reference property is required."));
@@ -53,7 +51,6 @@ public final class ConfigurationReferenceExistsValidator
implements ConstraintVa
ShardingSpherePreconditions.checkState(!poolProperty.isEmpty() &&
!poolProperty.contains("."),
() -> new ValidationException("Configuration pool must be a
property on the annotated object."));
allowEmpty = constraintAnnotation.allowEmpty();
- message = constraintAnnotation.message();
}
private String[] parseReferencePaths(final String referencePath) {
@@ -106,7 +103,7 @@ public final class ConfigurationReferenceExistsValidator
implements ConstraintVa
return true;
}
context.disableDefaultConstraintViolation();
- context.buildConstraintViolationWithTemplate(message.replace("{pool}",
poolProperty).replace("{reference}", (String)
value)).addPropertyNode(rootProperty).addConstraintViolation();
+
context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate()).addPropertyNode(rootProperty).addConstraintViolation();
return false;
}
diff --git
a/infra/common/src/main/java/org/apache/shardingsphere/infra/config/rule/validator/constraint/unique/UniqueTableNamesValidator.java
b/infra/common/src/main/java/org/apache/shardingsphere/infra/config/rule/validator/constraint/unique/UniqueTableNamesValidator.java
index 283b1ff39d5..a29c888e2be 100644
---
a/infra/common/src/main/java/org/apache/shardingsphere/infra/config/rule/validator/constraint/unique/UniqueTableNamesValidator.java
+++
b/infra/common/src/main/java/org/apache/shardingsphere/infra/config/rule/validator/constraint/unique/UniqueTableNamesValidator.java
@@ -39,7 +39,7 @@ public final class UniqueTableNamesValidator implements
ConstraintValidator<Uniq
return true;
}
context.disableDefaultConstraintViolation();
- context.buildConstraintViolationWithTemplate(String.format("must not
contain duplicate table names `%s`", String.join(", ",
duplicatedTableNames))).addConstraintViolation();
+
context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate()).addConstraintViolation();
return false;
}
diff --git
a/infra/common/src/test/java/org/apache/shardingsphere/infra/config/rule/validator/constraint/reference/ConfigurationReferenceExistsValidatorTest.java
b/infra/common/src/test/java/org/apache/shardingsphere/infra/config/rule/validator/constraint/reference/ConfigurationReferenceExistsValidatorTest.java
index 931bf608e94..29dd79c7438 100644
---
a/infra/common/src/test/java/org/apache/shardingsphere/infra/config/rule/validator/constraint/reference/ConfigurationReferenceExistsValidatorTest.java
+++
b/infra/common/src/test/java/org/apache/shardingsphere/infra/config/rule/validator/constraint/reference/ConfigurationReferenceExistsValidatorTest.java
@@ -52,14 +52,22 @@ class ConfigurationReferenceExistsValidatorTest {
Set<ConstraintViolation<DirectConfiguration>> actual =
VALIDATOR.validate(new DirectConfiguration("bar_provider",
Collections.singletonMap("foo_provider", "configured")));
assertThat(actual.size(), is(1));
assertThat(actual.iterator().next().getPropertyPath().toString(),
is("providerName"));
- assertThat(actual.iterator().next().getMessage(), is("references
unconfigured providers `bar_provider`"));
+ assertThat(actual.iterator().next().getMessage(), is("references
unconfigured providers"));
+ }
+
+ @Test
+ void assertUnconfiguredReferenceWithTemplateCharacters() {
+ Collection<ConstraintViolation<DirectConfiguration>> actual =
VALIDATOR.validate(new DirectConfiguration("bar_{message}_${7*7}",
Collections.singletonMap("foo_provider", "configured")));
+ assertThat(actual.size(), is(1));
+ assertThat(actual.iterator().next().getPropertyPath().toString(),
is("providerName"));
+ assertThat(actual.iterator().next().getMessage(), is("references
unconfigured providers"));
}
@Test
void assertUnconfiguredReferenceWithMissingPool() {
Set<ConstraintViolation<DirectConfiguration>> actual =
VALIDATOR.validate(new DirectConfiguration("bar_provider", null));
assertThat(actual.size(), is(1));
- assertThat(actual.iterator().next().getMessage(), is("references
unconfigured providers `bar_provider`"));
+ assertThat(actual.iterator().next().getMessage(), is("references
unconfigured providers"));
}
@Test
@@ -76,7 +84,7 @@ class ConfigurationReferenceExistsValidatorTest {
Set<ConstraintViolation<NestedConfiguration>> actual =
VALIDATOR.validate(config);
assertThat(actual.size(), is(1));
assertThat(actual.iterator().next().getPropertyPath().toString(),
is("groups"));
- assertThat(actual.iterator().next().getMessage(), is("references
unconfigured algorithms `bar_algorithm`"));
+ assertThat(actual.iterator().next().getMessage(), is("references
unconfigured algorithms"));
}
@Test
@@ -87,7 +95,7 @@ class ConfigurationReferenceExistsValidatorTest {
Collections.singletonMap("foo_algorithm", "configured"));
Set<ConstraintViolation<NestedConfiguration>> actual =
VALIDATOR.validate(config);
assertThat(actual.size(), is(1));
- assertThat(actual.iterator().next().getMessage(), is("references
unconfigured algorithms `first_missing`"));
+ assertThat(actual.iterator().next().getMessage(), is("references
unconfigured algorithms"));
}
@Test
diff --git
a/infra/common/src/test/java/org/apache/shardingsphere/infra/config/rule/validator/constraint/unique/UniqueTableNamesValidatorTest.java
b/infra/common/src/test/java/org/apache/shardingsphere/infra/config/rule/validator/constraint/unique/UniqueTableNamesValidatorTest.java
index 09fdbf63435..9543c870e8a 100644
---
a/infra/common/src/test/java/org/apache/shardingsphere/infra/config/rule/validator/constraint/unique/UniqueTableNamesValidatorTest.java
+++
b/infra/common/src/test/java/org/apache/shardingsphere/infra/config/rule/validator/constraint/unique/UniqueTableNamesValidatorTest.java
@@ -69,10 +69,11 @@ class UniqueTableNamesValidatorTest {
@ParameterizedTest(name = "{0}")
@MethodSource("duplicatedTablesArguments")
- void assertIsValidWithDuplicatedNames(final String name, final
Collection<?> tables, final String expectedMessage) {
+ void assertIsValidWithDuplicatedNames(final String name, final
Collection<?> tables) {
ConstraintValidatorContext context =
mock(ConstraintValidatorContext.class);
ConstraintViolationBuilder builder =
mock(ConstraintViolationBuilder.class);
-
when(context.buildConstraintViolationWithTemplate(expectedMessage)).thenReturn(builder);
+ when(context.getDefaultConstraintMessageTemplate()).thenReturn("must
not contain duplicate table names");
+ when(context.buildConstraintViolationWithTemplate("must not contain
duplicate table names")).thenReturn(builder);
assertFalse(validator.isValid(tables, context));
verify(context).disableDefaultConstraintViolation();
verify(builder).addConstraintViolation();
@@ -80,10 +81,10 @@ class UniqueTableNamesValidatorTest {
private static Stream<Arguments> duplicatedTablesArguments() {
return Stream.of(
- Arguments.of("Nonadjacent duplicated name",
createTables("foo_tbl", "bar_tbl", "foo_tbl"), "must not contain duplicate
table names `foo_tbl`"),
- Arguments.of("All duplicated names retain encounter order",
createTables("z_tbl", "a_tbl", "z_tbl", "a_tbl", "z_tbl"),
- "must not contain duplicate table names `z_tbl,
a_tbl`"),
- Arguments.of("Names read across different table types",
Arrays.asList(new Table("foo_tbl"), new OtherTable("foo_tbl")), "must not
contain duplicate table names `foo_tbl`"));
+ Arguments.of("Nonadjacent duplicated name",
createTables("foo_tbl", "bar_tbl", "foo_tbl")),
+ Arguments.of("Multiple duplicated names",
createTables("z_tbl", "a_tbl", "z_tbl", "a_tbl", "z_tbl")),
+ Arguments.of("Names read across different table types",
Arrays.asList(new Table("foo_tbl"), new OtherTable("foo_tbl"))),
+ Arguments.of("Template characters in duplicated names",
createTables("foo_{message}_${7*7}", "foo_{message}_${7*7}")));
}
@Test
diff --git
a/mcp/bootstrap/src/main/java/org/apache/shardingsphere/mcp/bootstrap/config/yaml/validator/YamlRuntimeDatabaseConfigurationsValidator.java
b/mcp/bootstrap/src/main/java/org/apache/shardingsphere/mcp/bootstrap/config/yaml/validator/YamlRuntimeDatabaseConfigurationsValidator.java
index b2ecbf3e2af..e058eb6796a 100644
---
a/mcp/bootstrap/src/main/java/org/apache/shardingsphere/mcp/bootstrap/config/yaml/validator/YamlRuntimeDatabaseConfigurationsValidator.java
+++
b/mcp/bootstrap/src/main/java/org/apache/shardingsphere/mcp/bootstrap/config/yaml/validator/YamlRuntimeDatabaseConfigurationsValidator.java
@@ -43,52 +43,52 @@ public final class
YamlRuntimeDatabaseConfigurationsValidator implements Constra
private boolean validateRuntimeDatabase(final String databaseName, final
YamlRuntimeDatabaseConfiguration config, final ConstraintValidatorContext
context) {
if (isPlaceholder(databaseName)) {
- addViolation(context, String.format("contains placeholder database
name `%s`", databaseName));
+ addViolation(context, "contains placeholder database name");
return false;
}
if (null == config) {
- addViolation(context, String.format("contains null configuration
for database `%s`", databaseName));
+ addViolation(context, "contains null database configuration");
return false;
}
- return validateNoPlaceholders(databaseName, config, context);
+ return validateNoPlaceholders(config, context);
}
- private boolean validateNoPlaceholders(final String databaseName, final
YamlRuntimeDatabaseConfiguration config, final ConstraintValidatorContext
context) {
- boolean result = validateNoPlaceholder(databaseName, "jdbcUrl",
config.getJdbcUrl(), context);
- result = validateNoPlaceholder(databaseName, "username",
config.getUsername(), context) && result;
- result = validateNoPlaceholder(databaseName, "driverClassName",
config.getDriverClassName(), context) && result;
- return validateNoPasswordPlaceholder(databaseName,
config.getPassword(), context) && result;
+ private boolean isPlaceholder(final String value) {
+ String actualValue = value.trim();
+ int startIndex = actualValue.indexOf('<');
+ return startIndex >= 0 && actualValue.indexOf('>', startIndex + 1) >
startIndex + 1;
+ }
+
+ private void addViolation(final ConstraintValidatorContext context, final
String message) {
+ context.disableDefaultConstraintViolation();
+
context.buildConstraintViolationWithTemplate(message).addConstraintViolation();
+ }
+
+ private boolean validateNoPlaceholders(final
YamlRuntimeDatabaseConfiguration config, final ConstraintValidatorContext
context) {
+ boolean result = validateNoPlaceholder("jdbcUrl", config.getJdbcUrl(),
context);
+ result = validateNoPlaceholder("username", config.getUsername(),
context) && result;
+ result = validateNoPlaceholder("driverClassName",
config.getDriverClassName(), context) && result;
+ return validateNoPasswordPlaceholder(config.getPassword(), context) &&
result;
}
- private boolean validateNoPlaceholder(final String databaseName, final
String propertyName, final String value, final ConstraintValidatorContext
context) {
+ private boolean validateNoPlaceholder(final String propertyName, final
String value, final ConstraintValidatorContext context) {
if (null == value || !isPlaceholder(value)) {
return true;
}
- addViolation(context, String.format("contains placeholder database
`%s` property `%s`", databaseName, propertyName));
+ addViolation(context, String.format("contains placeholder database
property `%s`", propertyName));
return false;
}
- private boolean validateNoPasswordPlaceholder(final String databaseName,
final String value, final ConstraintValidatorContext context) {
+ private boolean validateNoPasswordPlaceholder(final String value, final
ConstraintValidatorContext context) {
if (null == value || !isStandalonePlaceholder(value)) {
return true;
}
- addViolation(context, String.format("contains placeholder database
`%s` property `password`", databaseName));
+ addViolation(context, "contains placeholder database property
`password`");
return false;
}
- private boolean isPlaceholder(final String value) {
- String actualValue = value.trim();
- int startIndex = actualValue.indexOf('<');
- return startIndex >= 0 && actualValue.indexOf('>', startIndex + 1) >
startIndex + 1;
- }
-
private boolean isStandalonePlaceholder(final String value) {
String actualValue = value.trim();
return actualValue.startsWith("<") && actualValue.endsWith(">") &&
actualValue.length() > 2;
}
-
- private void addViolation(final ConstraintValidatorContext context, final
String message) {
- context.disableDefaultConstraintViolation();
-
context.buildConstraintViolationWithTemplate(message).addConstraintViolation();
- }
}
diff --git
a/mcp/bootstrap/src/test/java/org/apache/shardingsphere/mcp/bootstrap/config/yaml/swapper/YamlMCPLaunchConfigurationSwapperTest.java
b/mcp/bootstrap/src/test/java/org/apache/shardingsphere/mcp/bootstrap/config/yaml/swapper/YamlMCPLaunchConfigurationSwapperTest.java
index 9a925f4a9be..e54cda6a4cc 100644
---
a/mcp/bootstrap/src/test/java/org/apache/shardingsphere/mcp/bootstrap/config/yaml/swapper/YamlMCPLaunchConfigurationSwapperTest.java
+++
b/mcp/bootstrap/src/test/java/org/apache/shardingsphere/mcp/bootstrap/config/yaml/swapper/YamlMCPLaunchConfigurationSwapperTest.java
@@ -24,6 +24,8 @@ import
org.apache.shardingsphere.mcp.bootstrap.config.MCPLaunchConfiguration;
import
org.apache.shardingsphere.mcp.bootstrap.config.yaml.config.YamlMCPLaunchConfiguration;
import
org.apache.shardingsphere.mcp.support.database.metadata.jdbc.RuntimeDatabaseConfiguration;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
import org.yaml.snakeyaml.constructor.ConstructorException;
import java.util.Collections;
@@ -233,12 +235,9 @@ class YamlMCPLaunchConfigurationSwapperTest {
@Test
void assertSwapToObjectWithNullRuntimeDatabaseConfiguration() {
- String yamlContent = "transport:\n"
- + " type: STDIO\n"
- + "runtimeDatabases:\n"
- + " logic_db:\n";
+ String yamlContent = "transport:\n" + " type: STDIO\n" +
"runtimeDatabases:\n" + " foo_{message}:\n";
IllegalArgumentException actual =
assertThrows(IllegalArgumentException.class, () ->
swapper.swapToObject(YamlEngine.unmarshal(yamlContent,
YamlMCPLaunchConfiguration.class)));
- assertThat(actual.getMessage(), is("MCP launch configuration property
`runtimeDatabases` contains null configuration for database `logic_db`."));
+ assertThat(actual.getMessage(), is("MCP launch configuration property
`runtimeDatabases` contains null database configuration."));
}
@Test
@@ -258,44 +257,31 @@ class YamlMCPLaunchConfigurationSwapperTest {
@Test
void assertSwapToObjectWithPlaceholderRuntimeDatabaseName() {
- String yamlContent = "transport:\n"
- + " type: STDIO\n"
- + "runtimeDatabases:\n"
- + " <unresolved-database>:\n"
- + " jdbcUrl: jdbc:mysql://localhost:3306/logic_db\n"
- + " username: demo\n"
- + " password: ''\n"
- + " driverClassName: com.mysql.cj.jdbc.Driver\n";
+ String yamlContent = "transport:\n" + " type: STDIO\n" +
"runtimeDatabases:\n" + " <foo_{message}>:\n" + " jdbcUrl:
jdbc:mysql://localhost:3306/logic_db\n" + " username: demo\n"
+ + " password: ''\n" + " driverClassName:
com.mysql.cj.jdbc.Driver\n";
IllegalArgumentException actual =
assertThrows(IllegalArgumentException.class, () ->
swapper.swapToObject(YamlEngine.unmarshal(yamlContent,
YamlMCPLaunchConfiguration.class)));
- assertThat(actual.getMessage(), is("MCP launch configuration property
`runtimeDatabases` contains placeholder database name
`<unresolved-database>`."));
+ assertThat(actual.getMessage(), is("MCP launch configuration property
`runtimeDatabases` contains placeholder database name."));
}
- @Test
- void assertSwapToObjectWithPlaceholderJdbcUrl() {
- String yamlContent = "transport:\n"
- + " type: STDIO\n"
- + "runtimeDatabases:\n"
- + " logic_db:\n"
- + " jdbcUrl: jdbc:mysql://<unresolved-host>:3306/logic_db\n"
- + " username: demo\n"
- + " password: ''\n"
- + " driverClassName: com.mysql.cj.jdbc.Driver\n";
+ @ParameterizedTest(name = "{0}")
+ @CsvSource({
+ "JDBC URL, jdbc:mysql://<unresolved-host>:3306/logic_db, demo,
com.mysql.cj.jdbc.Driver, jdbcUrl",
+ "username, jdbc:mysql://localhost:3306/logic_db,
<unresolved-username>, com.mysql.cj.jdbc.Driver, username",
+ "driver class name, jdbc:mysql://localhost:3306/logic_db, demo,
<unresolved-driver>, driverClassName"
+ })
+ void assertSwapToObjectWithPlaceholderRuntimeDatabaseProperty(final String
name, final String jdbcUrl, final String username, final String
driverClassName, final String propertyName) {
+ String yamlContent = "transport:\n" + " type: STDIO\n" +
"runtimeDatabases:\n" + " foo_{message}:\n" + " jdbcUrl: " + jdbcUrl + "\n"
+ " username: " + username + "\n"
+ + " password: ''\n" + " driverClassName: " +
driverClassName + "\n";
IllegalArgumentException actual =
assertThrows(IllegalArgumentException.class, () ->
swapper.swapToObject(YamlEngine.unmarshal(yamlContent,
YamlMCPLaunchConfiguration.class)));
- assertThat(actual.getMessage(), is("MCP launch configuration property
`runtimeDatabases` contains placeholder database `logic_db` property
`jdbcUrl`."));
+ assertThat(actual.getMessage(), is(String.format("MCP launch
configuration property `runtimeDatabases` contains placeholder database
property `%s`.", propertyName)));
}
@Test
void assertSwapToObjectWithPlaceholderPassword() {
- String yamlContent = "transport:\n"
- + " type: STDIO\n"
- + "runtimeDatabases:\n"
- + " logic_db:\n"
- + " jdbcUrl: jdbc:mysql://localhost:3306/logic_db\n"
- + " username: demo\n"
- + " password: <unresolved-password>\n"
- + " driverClassName: com.mysql.cj.jdbc.Driver\n";
+ String yamlContent = "transport:\n" + " type: STDIO\n" +
"runtimeDatabases:\n" + " foo_{message}:\n" + " jdbcUrl:
jdbc:mysql://localhost:3306/logic_db\n" + " username: demo\n"
+ + " password: <unresolved-password>\n" + "
driverClassName: com.mysql.cj.jdbc.Driver\n";
IllegalArgumentException actual =
assertThrows(IllegalArgumentException.class, () ->
swapper.swapToObject(YamlEngine.unmarshal(yamlContent,
YamlMCPLaunchConfiguration.class)));
- assertThat(actual.getMessage(), is("MCP launch configuration property
`runtimeDatabases` contains placeholder database `logic_db` property
`password`."));
+ assertThat(actual.getMessage(), is("MCP launch configuration property
`runtimeDatabases` contains placeholder database property `password`."));
}
@Test