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 49d060c818c Validate algorithm types at configuration entry points
(#40075)
49d060c818c is described below
commit 49d060c818c99a420ba22564031d63cf52a79709
Author: Liang Zhang <[email protected]>
AuthorDate: Tue Oct 6 16:37:42 2026 +0800
Validate algorithm types at configuration entry points (#40075)
---
.../encrypt/config/EncryptRuleConfiguration.java | 3 +-
.../config/EncryptRuleConfigurationTest.java | 15 +
.../mask/config/MaskRuleConfiguration.java | 3 +-
.../mask/config/MaskRuleConfigurationTest.java | 15 +
.../ReadwriteSplittingRuleConfiguration.java | 3 +-
.../ReadwriteSplittingRuleConfigurationTest.java | 16 +
.../shadow/config/ShadowRuleConfiguration.java | 3 +-
.../shadow/config/ShadowRuleConfigurationTest.java | 18 ++
.../api/config/ShardingRuleConfiguration.java | 9 +-
.../api/config/ShardingRuleConfigurationTest.java | 29 ++
infra/algorithm/core/pom.xml | 4 +
.../core/config/AlgorithmConfiguration.java | 5 +-
.../core/config/AlgorithmConfigurationTest.java | 20 +-
.../reachability-metadata.json | 324 +++++++++++++++++++++
.../config/AuthorityRuleConfiguration.java | 5 +-
.../config/AuthorityRuleConfigurationTest.java | 26 ++
.../config/PipelineProcessConfiguration.java | 5 +
.../progress/config/PipelineReadConfiguration.java | 3 +
.../config/PipelineWriteConfiguration.java | 3 +
...PipelineProcessConfigurationPersistService.java | 24 +-
20 files changed, 516 insertions(+), 17 deletions(-)
diff --git
a/features/encrypt/api/src/main/java/org/apache/shardingsphere/encrypt/config/EncryptRuleConfiguration.java
b/features/encrypt/api/src/main/java/org/apache/shardingsphere/encrypt/config/EncryptRuleConfiguration.java
index af880959b8e..32aa90569c3 100644
---
a/features/encrypt/api/src/main/java/org/apache/shardingsphere/encrypt/config/EncryptRuleConfiguration.java
+++
b/features/encrypt/api/src/main/java/org/apache/shardingsphere/encrypt/config/EncryptRuleConfiguration.java
@@ -51,7 +51,8 @@ public final class EncryptRuleConfiguration implements
DatabaseRuleConfiguration
private final Collection<@NotNull EncryptTableRuleConfiguration> tables;
@NotNull
- @SPITypeExists(spiClassName =
"org.apache.shardingsphere.encrypt.spi.EncryptAlgorithm")
+ @Valid
+ @SPITypeExists(spiClassName =
"org.apache.shardingsphere.encrypt.spi.EncryptAlgorithm", groups =
RuleConfigurationTypeValidationGroup.class)
private final Map<@NotBlank String, @NotNull AlgorithmConfiguration>
encryptors;
@Override
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 e295c92d717..2d641e0811a 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
@@ -90,6 +90,21 @@ class EncryptRuleConfigurationTest {
return createRuleConfiguration(Arrays.asList(fooColumnConfig,
barColumnConfig), Collections.singletonMap("foo_encryptor", new
AlgorithmConfiguration("FIXTURE", new Properties())));
}
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("algorithmTypeArguments")
+ void assertValidateAlgorithmType(final String name, final String type,
final String expectedMessage) {
+ EncryptRuleConfiguration ruleConfig = new
EncryptRuleConfiguration(Collections.emptyList(),
Collections.singletonMap("foo_encryptor", new AlgorithmConfiguration(type, new
Properties())));
+ InvalidRuleConfigurationException actual =
assertThrows(InvalidRuleConfigurationException.class, () ->
RuleConfigurationValidator.validate(ruleConfig));
+ assertThat(actual.getMessage(), is("Invalid 'EncryptRuleConfiguration'
rule, error message is: " + expectedMessage));
+ }
+
+ private static Stream<Arguments> algorithmTypeArguments() {
+ return Stream.of(
+ Arguments.of("Null encryptor type before SPI", null, "Property
`encryptors[foo_encryptor].type` Type is required."),
+ Arguments.of("Empty encryptor type before SPI", "", "Property
`encryptors[foo_encryptor].type` Type is required."),
+ Arguments.of("Whitespace encryptor type reaches SPI", " ",
"Property `encryptors` does not match an available SPI implementation."));
+ }
+
@ParameterizedTest(name = "{0}")
@MethodSource("invalidRuleConfigurationArguments")
void assertValidateInvalidRuleConfiguration(final String name, final
EncryptRuleConfiguration ruleConfig) {
diff --git
a/features/mask/api/src/main/java/org/apache/shardingsphere/mask/config/MaskRuleConfiguration.java
b/features/mask/api/src/main/java/org/apache/shardingsphere/mask/config/MaskRuleConfiguration.java
index e58e4cff502..f4c4660e2c5 100644
---
a/features/mask/api/src/main/java/org/apache/shardingsphere/mask/config/MaskRuleConfiguration.java
+++
b/features/mask/api/src/main/java/org/apache/shardingsphere/mask/config/MaskRuleConfiguration.java
@@ -50,7 +50,8 @@ public final class MaskRuleConfiguration implements
DatabaseRuleConfiguration, E
private final Collection<@NotNull MaskTableRuleConfiguration> tables;
@NotNull
- @SPITypeExists(spiClassName =
"org.apache.shardingsphere.mask.spi.MaskAlgorithm")
+ @Valid
+ @SPITypeExists(spiClassName =
"org.apache.shardingsphere.mask.spi.MaskAlgorithm", groups =
RuleConfigurationTypeValidationGroup.class)
private final Map<@NotBlank String, @NotNull AlgorithmConfiguration>
maskAlgorithms;
@Override
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 9b83e3c8e5a..7ab22f97410 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
@@ -73,6 +73,21 @@ class MaskRuleConfigurationTest {
Collections.singletonMap("foo_mask", new
AlgorithmConfiguration("FIXTURE", new Properties())))));
}
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("algorithmTypeArguments")
+ void assertValidateAlgorithmType(final String name, final String type,
final String expectedMessage) {
+ MaskRuleConfiguration ruleConfig = new
MaskRuleConfiguration(Collections.emptyList(),
Collections.singletonMap("foo_mask", new AlgorithmConfiguration(type, new
Properties())));
+ InvalidRuleConfigurationException actual =
assertThrows(InvalidRuleConfigurationException.class, () ->
RuleConfigurationValidator.validate(ruleConfig));
+ assertThat(actual.getMessage(), is("Invalid 'MaskRuleConfiguration'
rule, error message is: " + expectedMessage));
+ }
+
+ private static Stream<Arguments> algorithmTypeArguments() {
+ return Stream.of(
+ Arguments.of("Null mask algorithm type before SPI", null,
"Property `maskAlgorithms[foo_mask].type` Type is required."),
+ Arguments.of("Empty mask algorithm type before SPI", "",
"Property `maskAlgorithms[foo_mask].type` Type is required."),
+ Arguments.of("Whitespace mask algorithm type reaches SPI", "
", "Property `maskAlgorithms` does not match an available SPI
implementation."));
+ }
+
@ParameterizedTest(name = "{0}")
@MethodSource("invalidRuleConfigurationArguments")
void assertValidateInvalidRuleConfiguration(final String name, final
MaskRuleConfiguration ruleConfig) {
diff --git
a/features/readwrite-splitting/api/src/main/java/org/apache/shardingsphere/readwritesplitting/config/ReadwriteSplittingRuleConfiguration.java
b/features/readwrite-splitting/api/src/main/java/org/apache/shardingsphere/readwritesplitting/config/ReadwriteSplittingRuleConfiguration.java
index 1dd16925812..701b4f5229a 100644
---
a/features/readwrite-splitting/api/src/main/java/org/apache/shardingsphere/readwritesplitting/config/ReadwriteSplittingRuleConfiguration.java
+++
b/features/readwrite-splitting/api/src/main/java/org/apache/shardingsphere/readwritesplitting/config/ReadwriteSplittingRuleConfiguration.java
@@ -46,6 +46,7 @@ public final class ReadwriteSplittingRuleConfiguration
implements DatabaseRuleCo
private final Collection<@NotNull
ReadwriteSplittingDataSourceGroupRuleConfiguration> dataSourceGroups;
@NotNull
- @SPITypeExists(spiClassName =
"org.apache.shardingsphere.infra.algorithm.loadbalancer.spi.LoadBalanceAlgorithm")
+ @Valid
+ @SPITypeExists(spiClassName =
"org.apache.shardingsphere.infra.algorithm.loadbalancer.spi.LoadBalanceAlgorithm",
groups = RuleConfigurationTypeValidationGroup.class)
private final Map<@NotBlank String, @NotNull AlgorithmConfiguration>
loadBalancers;
}
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 8060ea9983c..feb67831433 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
@@ -60,6 +60,22 @@ class ReadwriteSplittingRuleConfigurationTest {
Collections.singletonMap("foo_load_balancer", new
AlgorithmConfiguration("FIXTURE", new Properties())))));
}
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("algorithmTypeArguments")
+ void assertValidateAlgorithmType(final String name, final String type,
final String expectedMessage) {
+ ReadwriteSplittingRuleConfiguration ruleConfig = new
ReadwriteSplittingRuleConfiguration(Collections.emptyList(),
+ Collections.singletonMap("foo_load_balancer", new
AlgorithmConfiguration(type, new Properties())));
+ InvalidRuleConfigurationException actual =
assertThrows(InvalidRuleConfigurationException.class, () ->
RuleConfigurationValidator.validate(ruleConfig));
+ assertThat(actual.getMessage(), is("Invalid
'ReadwriteSplittingRuleConfiguration' rule, error message is: " +
expectedMessage));
+ }
+
+ private static Stream<Arguments> algorithmTypeArguments() {
+ return Stream.of(
+ Arguments.of("Null load balancer type before SPI", null,
"Property `loadBalancers[foo_load_balancer].type` Type is required."),
+ Arguments.of("Empty load balancer type before SPI", "",
"Property `loadBalancers[foo_load_balancer].type` Type is required."),
+ Arguments.of("Whitespace load balancer type reaches SPI", " ",
"Property `loadBalancers` does not match an available SPI implementation."));
+ }
+
@ParameterizedTest(name = "{0}")
@MethodSource("invalidRuleConfigurationArguments")
void assertValidateInvalidRuleConfiguration(final String name, final
ReadwriteSplittingRuleConfiguration ruleConfig) {
diff --git
a/features/shadow/api/src/main/java/org/apache/shardingsphere/shadow/config/ShadowRuleConfiguration.java
b/features/shadow/api/src/main/java/org/apache/shardingsphere/shadow/config/ShadowRuleConfiguration.java
index fa04928d73b..4a51c67affd 100644
---
a/features/shadow/api/src/main/java/org/apache/shardingsphere/shadow/config/ShadowRuleConfiguration.java
+++
b/features/shadow/api/src/main/java/org/apache/shardingsphere/shadow/config/ShadowRuleConfiguration.java
@@ -53,7 +53,8 @@ public final class ShadowRuleConfiguration implements
DatabaseRuleConfiguration,
private Map<@NotBlank String, @NotNull ShadowTableConfiguration> tables =
new LinkedHashMap<>();
@NotNull
- @SPITypeExists(spiClassName =
"org.apache.shardingsphere.shadow.spi.ShadowAlgorithm")
+ @Valid
+ @SPITypeExists(spiClassName =
"org.apache.shardingsphere.shadow.spi.ShadowAlgorithm", groups =
RuleConfigurationTypeValidationGroup.class)
private Map<@NotBlank String, @NotNull AlgorithmConfiguration>
shadowAlgorithms = new LinkedHashMap<>();
private String defaultShadowAlgorithmName;
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 bbb051c6b8d..1fedec45649 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
@@ -32,6 +32,8 @@ import java.util.Map;
import java.util.Properties;
import java.util.stream.Stream;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -71,6 +73,22 @@ class ShadowRuleConfigurationTest {
return result;
}
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("algorithmTypeArguments")
+ void assertValidateAlgorithmType(final String name, final String type,
final String expectedMessage) {
+ ShadowRuleConfiguration ruleConfig =
createRuleConfiguration(Collections.emptyList(), Collections.emptyMap(),
+ Collections.singletonMap("foo_shadow_algorithm", new
AlgorithmConfiguration(type, new Properties())));
+ InvalidRuleConfigurationException actual =
assertThrows(InvalidRuleConfigurationException.class, () ->
RuleConfigurationValidator.validate(ruleConfig));
+ assertThat(actual.getMessage(), is("Invalid 'ShadowRuleConfiguration'
rule, error message is: " + expectedMessage));
+ }
+
+ private static Stream<Arguments> algorithmTypeArguments() {
+ return Stream.of(
+ Arguments.of("Null shadow algorithm type before SPI", null,
"Property `shadowAlgorithms[foo_shadow_algorithm].type` Type is required."),
+ Arguments.of("Empty shadow algorithm type before SPI", "",
"Property `shadowAlgorithms[foo_shadow_algorithm].type` Type is required."),
+ Arguments.of("Whitespace shadow algorithm type reaches SPI", "
", "Property `shadowAlgorithms` does not match an available SPI
implementation."));
+ }
+
@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/ShardingRuleConfiguration.java
b/features/sharding/api/src/main/java/org/apache/shardingsphere/sharding/api/config/ShardingRuleConfiguration.java
index 0ff03c9855f..303c5466d74 100644
---
a/features/sharding/api/src/main/java/org/apache/shardingsphere/sharding/api/config/ShardingRuleConfiguration.java
+++
b/features/sharding/api/src/main/java/org/apache/shardingsphere/sharding/api/config/ShardingRuleConfiguration.java
@@ -81,15 +81,18 @@ public final class ShardingRuleConfiguration implements
DatabaseRuleConfiguratio
private Map<@NotBlank String, @NotNull KeyGenerateStrategiesConfiguration>
keyGenerateStrategies = new LinkedHashMap<>();
@NotNull
- @SPITypeExists(spiClassName =
"org.apache.shardingsphere.sharding.spi.ShardingAlgorithm")
+ @Valid
+ @SPITypeExists(spiClassName =
"org.apache.shardingsphere.sharding.spi.ShardingAlgorithm", groups =
RuleConfigurationTypeValidationGroup.class)
private Map<@NotBlank String, @NotNull AlgorithmConfiguration>
shardingAlgorithms = new LinkedHashMap<>();
@NotNull
- @SPITypeExists(spiClassName =
"org.apache.shardingsphere.infra.algorithm.keygen.spi.KeyGenerateAlgorithm")
+ @Valid
+ @SPITypeExists(spiClassName =
"org.apache.shardingsphere.infra.algorithm.keygen.spi.KeyGenerateAlgorithm",
groups = RuleConfigurationTypeValidationGroup.class)
private Map<@NotBlank String, @NotNull AlgorithmConfiguration>
keyGenerators = new LinkedHashMap<>();
@NotNull
- @SPITypeExists(spiClassName =
"org.apache.shardingsphere.sharding.spi.ShardingAuditAlgorithm")
+ @Valid
+ @SPITypeExists(spiClassName =
"org.apache.shardingsphere.sharding.spi.ShardingAuditAlgorithm", groups =
RuleConfigurationTypeValidationGroup.class)
private Map<@NotBlank String, @NotNull AlgorithmConfiguration> auditors =
new LinkedHashMap<>();
@Override
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 8cb9a7a8404..dd5584f09f9 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
@@ -301,6 +301,35 @@ class ShardingRuleConfigurationTest {
new
SequenceKeyGenerateStrategiesRuleConfiguration("foo_key_generator", ""))));
}
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("algorithmTypeArguments")
+ void assertValidateAlgorithmType(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> algorithmTypeArguments() {
+ return Stream.of(
+ Arguments.of("Null sharding algorithm type before SPI",
createShardingAlgorithmsRuleConfiguration("foo_sharding", new
AlgorithmConfiguration(null, new Properties())),
+ "Property `shardingAlgorithms[foo_sharding].type` Type
is required."),
+ Arguments.of("Empty sharding algorithm type before SPI",
createShardingAlgorithmsRuleConfiguration("foo_sharding", new
AlgorithmConfiguration("", new Properties())),
+ "Property `shardingAlgorithms[foo_sharding].type` Type
is required."),
+ Arguments.of("Whitespace sharding algorithm type reaches SPI",
createShardingAlgorithmsRuleConfiguration("foo_sharding", new
AlgorithmConfiguration(" ", new Properties())),
+ "Property `shardingAlgorithms` does not match an
available SPI implementation."),
+ Arguments.of("Null key generator type before SPI",
createKeyGeneratorsRuleConfiguration("foo_key_generator", new
AlgorithmConfiguration(null, new Properties())),
+ "Property `keyGenerators[foo_key_generator].type` Type
is required."),
+ Arguments.of("Empty key generator type before SPI",
createKeyGeneratorsRuleConfiguration("foo_key_generator", new
AlgorithmConfiguration("", new Properties())),
+ "Property `keyGenerators[foo_key_generator].type` Type
is required."),
+ Arguments.of("Whitespace key generator type reaches SPI",
createKeyGeneratorsRuleConfiguration("foo_key_generator", new
AlgorithmConfiguration(" ", new Properties())),
+ "Property `keyGenerators` does not match an available
SPI implementation."),
+ Arguments.of("Null auditor type before SPI",
createAuditorsRuleConfiguration("foo_auditor", new AlgorithmConfiguration(null,
new Properties())),
+ "Property `auditors[foo_auditor].type` Type is
required."),
+ Arguments.of("Empty auditor type before SPI",
createAuditorsRuleConfiguration("foo_auditor", new AlgorithmConfiguration("",
new Properties())),
+ "Property `auditors[foo_auditor].type` Type is
required."),
+ Arguments.of("Whitespace auditor type reaches SPI",
createAuditorsRuleConfiguration("foo_auditor", new AlgorithmConfiguration(" ",
new Properties())),
+ "Property `auditors` does not match an available SPI
implementation."));
+ }
+
@ParameterizedTest(name = "{0}")
@MethodSource("invalidReferenceRuleConfigurationArguments")
void assertValidateInvalidReferenceRuleConfiguration(final String name,
final ShardingRuleConfiguration ruleConfig) {
diff --git a/infra/algorithm/core/pom.xml b/infra/algorithm/core/pom.xml
index 427321d2fab..e35bf290bc8 100644
--- a/infra/algorithm/core/pom.xml
+++ b/infra/algorithm/core/pom.xml
@@ -32,6 +32,10 @@
<artifactId>shardingsphere-mode-spi</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>jakarta.validation</groupId>
+ <artifactId>jakarta.validation-api</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
diff --git
a/infra/algorithm/core/src/main/java/org/apache/shardingsphere/infra/algorithm/core/config/AlgorithmConfiguration.java
b/infra/algorithm/core/src/main/java/org/apache/shardingsphere/infra/algorithm/core/config/AlgorithmConfiguration.java
index 333293bf53d..cf9391089c1 100644
---
a/infra/algorithm/core/src/main/java/org/apache/shardingsphere/infra/algorithm/core/config/AlgorithmConfiguration.java
+++
b/infra/algorithm/core/src/main/java/org/apache/shardingsphere/infra/algorithm/core/config/AlgorithmConfiguration.java
@@ -17,11 +17,10 @@
package org.apache.shardingsphere.infra.algorithm.core.config;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
import lombok.EqualsAndHashCode;
import lombok.Getter;
+import javax.validation.constraints.NotEmpty;
import java.util.Properties;
/**
@@ -31,12 +30,12 @@ import java.util.Properties;
@EqualsAndHashCode
public final class AlgorithmConfiguration {
+ @NotEmpty(message = "Type is required.")
private final String type;
private final Properties props;
public AlgorithmConfiguration(final String type, final Properties props) {
- Preconditions.checkArgument(!Strings.isNullOrEmpty(type), "Type is
required.");
this.type = type;
this.props = null == props ? new Properties() : props;
}
diff --git
a/infra/algorithm/core/src/test/java/org/apache/shardingsphere/infra/algorithm/core/config/AlgorithmConfigurationTest.java
b/infra/algorithm/core/src/test/java/org/apache/shardingsphere/infra/algorithm/core/config/AlgorithmConfigurationTest.java
index 9ab17192f4a..268413d6bc7 100644
---
a/infra/algorithm/core/src/test/java/org/apache/shardingsphere/infra/algorithm/core/config/AlgorithmConfigurationTest.java
+++
b/infra/algorithm/core/src/test/java/org/apache/shardingsphere/infra/algorithm/core/config/AlgorithmConfigurationTest.java
@@ -18,12 +18,17 @@
package org.apache.shardingsphere.infra.algorithm.core.config;
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;
import java.util.Properties;
+import java.util.stream.Stream;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
-import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.hamcrest.Matchers.sameInstance;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertTrue;
class AlgorithmConfigurationTest {
@@ -33,7 +38,7 @@ class AlgorithmConfigurationTest {
Properties props = new Properties();
AlgorithmConfiguration actual = new AlgorithmConfiguration("INLINE",
props);
assertThat(actual.getType(), is("INLINE"));
- assertThat(actual.getProps(), is(props));
+ assertThat(actual.getProps(), sameInstance(props));
}
@Test
@@ -43,8 +48,13 @@ class AlgorithmConfigurationTest {
assertTrue(actual.getProps().isEmpty());
}
- @Test
- void assertConstructWithEmptyType() {
- assertThat(assertThrows(IllegalArgumentException.class, () -> new
AlgorithmConfiguration("", new Properties())).getMessage(), is("Type is
required."));
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("provideTypes")
+ void assertConstructWithoutTypeValidation(final String name, final String
type) {
+ assertDoesNotThrow(() -> new AlgorithmConfiguration(type, new
Properties()));
+ }
+
+ private static Stream<Arguments> provideTypes() {
+ return Stream.of(Arguments.of("Null type", null), Arguments.of("Empty
type", ""), Arguments.of("Whitespace type", " "));
}
}
diff --git
a/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/infra-reachability-metadata/reachability-metadata.json
b/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/infra-reachability-metadata/reachability-metadata.json
index d5982bdd347..1c4ccbca1e1 100644
---
a/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/infra-reachability-metadata/reachability-metadata.json
+++
b/infra/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere/infra-reachability-metadata/reachability-metadata.json
@@ -460,6 +460,211 @@
}
]
},
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "type": "org.apache.bval.constraints.NotEmptyValidator",
+ "methods": [
+ {
+ "name": "<init>",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "type": "org.apache.bval.constraints.NotEmptyValidatorForCharSequence",
+ "methods": [
+ {
+ "name": "<init>",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "type": "org.apache.bval.constraints.NotEmptyValidatorForCollection",
+ "methods": [
+ {
+ "name": "<init>",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "type": "org.apache.bval.constraints.NotEmptyValidatorForMap",
+ "methods": [
+ {
+ "name": "<init>",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "type": "org.apache.bval.jsr.ApacheValidatorFactory",
+ "methods": [
+ {
+ "name": "<init>",
+ "parameterTypes": [
+ "javax.validation.spi.ConfigurationState"
+ ]
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "type": "org.apache.bval.jsr.ConstraintAnnotationAttributes$Types",
+ "fields": [
+ {
+ "name": "message"
+ },
+ {
+ "name": "groups"
+ },
+ {
+ "name": "payload"
+ },
+ {
+ "name": "validationAppliesTo"
+ },
+ {
+ "name": "value"
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "type": "org.apache.bval.jsr.valueextraction.FxExtractor$Activation",
+ "methods": [
+ {
+ "name": "<init>",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "type": "org.apache.bval.jsr.valueextraction.IterableElementExtractor",
+ "methods": [
+ {
+ "name": "<init>",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "type": "org.apache.bval.jsr.valueextraction.ListElementExtractor",
+ "methods": [
+ {
+ "name": "<init>",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "type": "org.apache.bval.jsr.valueextraction.MapExtractor"
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "type": "org.apache.bval.jsr.valueextraction.MapExtractor$ForKey",
+ "methods": [
+ {
+ "name": "<init>",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "type": "org.apache.bval.jsr.valueextraction.MapExtractor$ForValue",
+ "methods": [
+ {
+ "name": "<init>",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "type": "org.apache.bval.jsr.valueextraction.OptionalExtractor"
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "type":
"org.apache.bval.jsr.valueextraction.OptionalExtractor$ForDouble",
+ "methods": [
+ {
+ "name": "<init>",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "type": "org.apache.bval.jsr.valueextraction.OptionalExtractor$ForInt",
+ "methods": [
+ {
+ "name": "<init>",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "type": "org.apache.bval.jsr.valueextraction.OptionalExtractor$ForLong",
+ "methods": [
+ {
+ "name": "<init>",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "type":
"org.apache.bval.jsr.valueextraction.OptionalExtractor$ForObject",
+ "methods": [
+ {
+ "name": "<init>",
+ "parameterTypes": []
+ }
+ ]
+ },
{
"condition": {
"typeReached":
"org.apache.shardingsphere.infra.config.rule.validator.RuleConfigurationValidator"
@@ -623,6 +828,11 @@
"typeReached":
"org.apache.shardingsphere.infra.config.rule.validator.RuleConfigurationValidator"
},
"type":
"org.apache.shardingsphere.infra.algorithm.core.config.AlgorithmConfiguration",
+ "fields": [
+ {
+ "name": "type"
+ }
+ ],
"methods": [
{
"name": "getType",
@@ -630,6 +840,102 @@
}
]
},
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.infra.config.rule.validator.RuleConfigurationValidator"
+ },
+ "type": "javax.validation.constraints.NotEmpty",
+ "methods": [
+ {
+ "name": "message",
+ "parameterTypes": []
+ },
+ {
+ "name": "groups",
+ "parameterTypes": []
+ },
+ {
+ "name": "payload",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "type":
"org.apache.shardingsphere.infra.algorithm.core.config.AlgorithmConfiguration",
+ "fields": [
+ {
+ "name": "type"
+ }
+ ],
+ "methods": [
+ {
+ "name": "getType",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "type": "javax.validation.constraints.NotEmpty",
+ "methods": [
+ {
+ "name": "message",
+ "parameterTypes": []
+ },
+ {
+ "name": "groups",
+ "parameterTypes": []
+ },
+ {
+ "name": "payload",
+ "parameterTypes": []
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "type":
"org.apache.shardingsphere.data.pipeline.core.job.progress.config.PipelineProcessConfiguration",
+ "fields": [
+ {
+ "name": "read"
+ },
+ {
+ "name": "write"
+ },
+ {
+ "name": "streamChannel"
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "type":
"org.apache.shardingsphere.data.pipeline.core.job.progress.config.PipelineReadConfiguration",
+ "fields": [
+ {
+ "name": "rateLimiter"
+ }
+ ]
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "type":
"org.apache.shardingsphere.data.pipeline.core.job.progress.config.PipelineWriteConfiguration",
+ "fields": [
+ {
+ "name": "rateLimiter"
+ }
+ ]
+ },
{
"condition": {
"typeReached":
"org.apache.shardingsphere.infra.config.rule.validator.RuleConfigurationValidator"
@@ -1752,6 +2058,24 @@
},
"glob":
"org/apache/bval/jsr/valueextraction/DefaultExtractors.properties"
},
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "bundle": "org.apache.bval.jsr.ValidationMessages"
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "glob": "org/apache/bval/jsr/DefaultConstraints.properties"
+ },
+ {
+ "condition": {
+ "typeReached":
"org.apache.shardingsphere.data.pipeline.core.metadata.PipelineProcessConfigurationPersistService"
+ },
+ "glob":
"org/apache/bval/jsr/valueextraction/DefaultExtractors.properties"
+ },
{
"condition": {
"typeReached":
"org.apache.shardingsphere.infra.spi.RegisteredShardingSphereSPI"
diff --git
a/kernel/authority/api/src/main/java/org/apache/shardingsphere/authority/config/AuthorityRuleConfiguration.java
b/kernel/authority/api/src/main/java/org/apache/shardingsphere/authority/config/AuthorityRuleConfiguration.java
index 106fc233ad4..56c8a6e6eee 100644
---
a/kernel/authority/api/src/main/java/org/apache/shardingsphere/authority/config/AuthorityRuleConfiguration.java
+++
b/kernel/authority/api/src/main/java/org/apache/shardingsphere/authority/config/AuthorityRuleConfiguration.java
@@ -22,6 +22,7 @@ import lombok.RequiredArgsConstructor;
import
org.apache.shardingsphere.infra.algorithm.core.config.AlgorithmConfiguration;
import
org.apache.shardingsphere.infra.config.rule.scope.GlobalRuleConfiguration;
import
org.apache.shardingsphere.infra.config.rule.validator.constraint.spi.SPITypeExists;
+import
org.apache.shardingsphere.infra.config.rule.validator.group.RuleConfigurationTypeValidationGroup;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
@@ -41,10 +42,12 @@ public final class AuthorityRuleConfiguration implements
GlobalRuleConfiguration
private final Collection<@NotNull UserConfiguration> users;
@NotNull
- @SPITypeExists(spiClassName =
"org.apache.shardingsphere.authority.spi.PrivilegeProvider")
+ @Valid
+ @SPITypeExists(spiClassName =
"org.apache.shardingsphere.authority.spi.PrivilegeProvider", groups =
RuleConfigurationTypeValidationGroup.class)
private final AlgorithmConfiguration privilegeProvider;
@NotNull
+ @Valid
private final Map<@NotBlank String, @NotNull AlgorithmConfiguration>
authenticators;
private final String defaultAuthenticator;
diff --git
a/kernel/authority/api/src/test/java/org/apache/shardingsphere/authority/config/AuthorityRuleConfigurationTest.java
b/kernel/authority/api/src/test/java/org/apache/shardingsphere/authority/config/AuthorityRuleConfigurationTest.java
index 8b2c0d08304..8b69b394338 100644
---
a/kernel/authority/api/src/test/java/org/apache/shardingsphere/authority/config/AuthorityRuleConfigurationTest.java
+++
b/kernel/authority/api/src/test/java/org/apache/shardingsphere/authority/config/AuthorityRuleConfigurationTest.java
@@ -28,6 +28,8 @@ import java.util.Collections;
import java.util.Properties;
import java.util.stream.Stream;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -49,6 +51,8 @@ class AuthorityRuleConfigurationTest {
Collections.singleton(userConfig), privilegeProvider,
Collections.emptyMap(), null)),
Arguments.of("User with null hostname",
createRuleConfiguration(new UserConfiguration("foo_user", null, null, null,
false))),
Arguments.of("User with empty hostname",
createRuleConfiguration(new UserConfiguration("foo_user", null, "", null,
false))),
+ Arguments.of("Whitespace authenticator type remains nonempty",
new AuthorityRuleConfiguration(Collections.emptyList(), privilegeProvider,
+ Collections.singletonMap("foo_authenticator",
createAlgorithmConfiguration(" ")), null)),
Arguments.of("Complete configuration", new
AuthorityRuleConfiguration(Collections.singleton(
new UserConfiguration("foo_admin", "foo_password",
"localhost", "foo_authenticator", true)), privilegeProvider,
Collections.singletonMap("foo_authenticator",
createAlgorithmConfiguration("MD5")), "foo_authenticator")));
@@ -58,6 +62,28 @@ class AuthorityRuleConfigurationTest {
return new AlgorithmConfiguration(type, new Properties());
}
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("algorithmTypeArguments")
+ void assertValidateAlgorithmType(final String name, final
AuthorityRuleConfiguration ruleConfig, final String expectedMessage) {
+ InvalidRuleConfigurationException actual =
assertThrows(InvalidRuleConfigurationException.class, () ->
RuleConfigurationValidator.validate(ruleConfig));
+ assertThat(actual.getMessage(), is("Invalid
'AuthorityRuleConfiguration' rule, error message is: " + expectedMessage));
+ }
+
+ private static Stream<Arguments> algorithmTypeArguments() {
+ AlgorithmConfiguration privilegeProvider =
createAlgorithmConfiguration("FIXTURE");
+ return Stream.of(
+ Arguments.of("Null privilege provider type before SPI", new
AuthorityRuleConfiguration(Collections.emptyList(),
createAlgorithmConfiguration(null), Collections.emptyMap(), null),
+ "Property `privilegeProvider.type` Type is required."),
+ Arguments.of("Empty privilege provider type before SPI", new
AuthorityRuleConfiguration(Collections.emptyList(),
createAlgorithmConfiguration(""), Collections.emptyMap(), null),
+ "Property `privilegeProvider.type` Type is required."),
+ Arguments.of("Whitespace privilege provider type reaches SPI",
new AuthorityRuleConfiguration(Collections.emptyList(),
createAlgorithmConfiguration(" "), Collections.emptyMap(), null),
+ "Property `privilegeProvider` does not match an
available SPI implementation."),
+ Arguments.of("Null authenticator type", new
AuthorityRuleConfiguration(Collections.emptyList(), privilegeProvider,
+ Collections.singletonMap("foo_authenticator",
createAlgorithmConfiguration(null)), null), "Property
`authenticators[foo_authenticator].type` Type is required."),
+ Arguments.of("Empty authenticator type", new
AuthorityRuleConfiguration(Collections.emptyList(), privilegeProvider,
+ Collections.singletonMap("foo_authenticator",
createAlgorithmConfiguration("")), null), "Property
`authenticators[foo_authenticator].type` Type is required."));
+ }
+
@ParameterizedTest(name = "{0}")
@MethodSource("invalidRuleConfigurationArguments")
void assertValidateInvalidRuleConfiguration(final String name, final
AuthorityRuleConfiguration ruleConfig) {
diff --git
a/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/job/progress/config/PipelineProcessConfiguration.java
b/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/job/progress/config/PipelineProcessConfiguration.java
index 99064e12d69..d742f86b612 100644
---
a/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/job/progress/config/PipelineProcessConfiguration.java
+++
b/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/job/progress/config/PipelineProcessConfiguration.java
@@ -22,6 +22,8 @@ import lombok.RequiredArgsConstructor;
import lombok.ToString;
import
org.apache.shardingsphere.infra.algorithm.core.config.AlgorithmConfiguration;
+import javax.validation.Valid;
+
/**
* Pipeline process configuration.
*/
@@ -30,9 +32,12 @@ import
org.apache.shardingsphere.infra.algorithm.core.config.AlgorithmConfigurat
@ToString
public final class PipelineProcessConfiguration {
+ @Valid
private final PipelineReadConfiguration read;
+ @Valid
private final PipelineWriteConfiguration write;
+ @Valid
private final AlgorithmConfiguration streamChannel;
}
diff --git
a/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/job/progress/config/PipelineReadConfiguration.java
b/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/job/progress/config/PipelineReadConfiguration.java
index 7086aff61a9..4199264c04c 100644
---
a/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/job/progress/config/PipelineReadConfiguration.java
+++
b/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/job/progress/config/PipelineReadConfiguration.java
@@ -22,6 +22,8 @@ import lombok.RequiredArgsConstructor;
import lombok.ToString;
import
org.apache.shardingsphere.infra.algorithm.core.config.AlgorithmConfiguration;
+import javax.validation.Valid;
+
/**
* Pipeline read configuration.
*/
@@ -36,5 +38,6 @@ public final class PipelineReadConfiguration {
private final Integer shardingSize;
+ @Valid
private final AlgorithmConfiguration rateLimiter;
}
diff --git
a/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/job/progress/config/PipelineWriteConfiguration.java
b/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/job/progress/config/PipelineWriteConfiguration.java
index 859f4481501..bb93d52add3 100644
---
a/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/job/progress/config/PipelineWriteConfiguration.java
+++
b/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/job/progress/config/PipelineWriteConfiguration.java
@@ -22,6 +22,8 @@ import lombok.RequiredArgsConstructor;
import lombok.ToString;
import
org.apache.shardingsphere.infra.algorithm.core.config.AlgorithmConfiguration;
+import javax.validation.Valid;
+
/**
* Pipeline write configuration.
*/
@@ -34,5 +36,6 @@ public final class PipelineWriteConfiguration {
private final Integer batchSize;
+ @Valid
private final AlgorithmConfiguration rateLimiter;
}
diff --git
a/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/metadata/PipelineProcessConfigurationPersistService.java
b/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/metadata/PipelineProcessConfigurationPersistService.java
index 735c0cd6f57..15b7af55646 100644
---
a/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/metadata/PipelineProcessConfigurationPersistService.java
+++
b/kernel/data-pipeline/core/src/main/java/org/apache/shardingsphere/data/pipeline/core/metadata/PipelineProcessConfigurationPersistService.java
@@ -18,18 +18,28 @@
package org.apache.shardingsphere.data.pipeline.core.metadata;
import com.google.common.base.Strings;
+import org.apache.bval.jsr.ApacheValidationProvider;
import org.apache.shardingsphere.data.pipeline.core.context.PipelineContextKey;
import org.apache.shardingsphere.data.pipeline.core.job.api.PipelineAPIFactory;
import
org.apache.shardingsphere.data.pipeline.core.job.progress.config.PipelineProcessConfiguration;
import
org.apache.shardingsphere.data.pipeline.core.job.progress.config.yaml.config.YamlPipelineProcessConfiguration;
import
org.apache.shardingsphere.data.pipeline.core.job.progress.config.yaml.swapper.YamlPipelineProcessConfigurationSwapper;
+import org.apache.shardingsphere.infra.exception.ShardingSpherePreconditions;
import org.apache.shardingsphere.infra.util.yaml.YamlEngine;
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import java.util.Collection;
+import java.util.stream.Collectors;
+
/**
* Pipeline process configuration persist service.
*/
public final class PipelineProcessConfigurationPersistService implements
PipelineMetaDataPersistService<PipelineProcessConfiguration> {
+ private static final Validator VALIDATOR =
Validation.byProvider(ApacheValidationProvider.class).configure().buildValidatorFactory().getValidator();
+
private final YamlPipelineProcessConfigurationSwapper swapper = new
YamlPipelineProcessConfigurationSwapper();
@Override
@@ -39,12 +49,24 @@ public final class
PipelineProcessConfigurationPersistService implements Pipelin
return null;
}
YamlPipelineProcessConfiguration yamlConfig =
YamlEngine.unmarshal(yamlText, YamlPipelineProcessConfiguration.class, true);
- return swapper.swapToObject(yamlConfig);
+ PipelineProcessConfiguration result = swapper.swapToObject(yamlConfig);
+ validate(result);
+ return result;
}
@Override
public void persist(final PipelineContextKey contextKey, final String
jobType, final PipelineProcessConfiguration processConfig) {
+ validate(processConfig);
String yamlText =
YamlEngine.marshal(swapper.swapToYamlConfiguration(processConfig));
PipelineAPIFactory.getPipelineGovernanceFacade(contextKey).getMetaDataFacade().getProcessConfiguration().persist(jobType,
yamlText);
}
+
+ private void validate(final PipelineProcessConfiguration processConfig) {
+ if (null == processConfig) {
+ return;
+ }
+ Collection<ConstraintViolation<PipelineProcessConfiguration>>
violations = VALIDATOR.validate(processConfig);
+ ShardingSpherePreconditions.checkMustEmpty(violations,
+ () -> new
IllegalArgumentException(violations.stream().map(ConstraintViolation::getMessage).distinct().sorted().collect(Collectors.joining(";
"))));
+ }
}