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]

Reply via email to