nzw921rx opened a new pull request, #11048:
URL: https://github.com/apache/seatunnel/pull/11048
### Purpose of this pull request
Add `ConditionOperator.EXTENSION` to allow connectors to plug custom
validation logic into the existing `Condition` framework.
**Problem:**
Built-in operators (`greaterOrEqual`, `notBlank`, `notEmpty`, etc.) handle
single-value checks well, but connectors sometimes need structural validation
on complex types:
- Validate every entry in `List<Map<String, Object>>` contains required keys
(`field`, `type`)
- Validate `table_configs` child configs have valid numeric ranges across
nested maps
Today this kind of logic is scattered in imperative code like
`buildWithConfig()`, making it invisible to the declarative `OptionRule`
system, REST metadata API, and CLI tooling.
**Solution:**
Introduce `ConditionExtension<T>` interface + `ConditionOperator.EXTENSION`
enum constant. Connector developers implement the interface and wire it via
`Conditions.extension(option, ext)`.
The EXTENSION operator is a first-class citizen in the existing pipeline:
- Reuses `valueConstraints` evaluation in `ConfigValidator` — no changes to
`OptionRule` or `ConfigValidator`
- `Conditions.extension(Option<T>, ConditionExtension<T>)` enforces type
safety at compile time
- Chains with `.and()` / `.or()` and mixes freely with any built-in operator
- REST metadata exposes `conditionOperator: "EXTENSION"` with `expectValue`
from `description()`
- Supports two error reporting modes: return `false` for auto-composed
messages, or throw `OptionValidationException` for context-rich details
**Usage:**
```java
// Inline anonymous class
OptionRule.builder()
.required(PORT, Conditions.extension(PORT, new
ConditionExtension<Integer>() {
@Override public String description() { return "must be between 1
and 65535"; }
@Override public boolean evaluate(ReadonlyConfig cfg, Integer v) {
return v != null && v >= 1 && v <= 65535;
}
}))
.build();
// Chain with built-in operators
OptionRule.builder()
.required(PORT,
Conditions.greaterOrEqual(PORT, 1)
.and(Conditions.extension(PORT, new
ConditionExtension<Integer>() {
@Override public String description() { return "must be a
valid port"; }
@Override public boolean evaluate(ReadonlyConfig cfg,
Integer v) {
return v != null && v <= 65535;
}
})))
.build();
// Static inner class for complex nested validation
static class ChildConfigRangeValidator
implements ConditionExtension<List<Map<String, Object>>> {
@Override
public String description() {
return "each child config must have valid numeric ranges";
}
@Override
public boolean evaluate(ReadonlyConfig config, List<Map<String, Object>>
value) {
if (value == null || value.isEmpty()) return false;
for (Map<String, Object> child : value) {
if (!child.containsKey("field") || !child.containsKey("type")) {
return false;
}
}
return true;
}
}
OptionRule.builder()
.required(TABLE_CONFIGS,
Conditions.extension(TABLE_CONFIGS, new ChildConfigRangeValidator()
{}))
.build();
```
### Does this PR introduce _any_ user-facing change?
No.
### How was this patch tested?
```bash
./mvnw -pl seatunnel-api test
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]