This is an automated email from the ASF dual-hosted git repository.

github-merge-queue[bot] pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/seatunnel.git


The following commit(s) were added to refs/heads/dev by this push:
     new b3898b62d7 [Improve][Connector-V2] Validate nonblank MaxCompute source 
endpoint (#12690)
b3898b62d7 is described below

commit b3898b62d79db47d4b213c830da8745edd8fc678
Author: Supidan <[email protected]>
AuthorDate: Mon Oct 12 12:02:54 2026 +0000

    [Improve][Connector-V2] Validate nonblank MaxCompute source endpoint 
(#12690)
    
    Co-authored-by: Supidan <[email protected]>
---
 docs/en/connectors/source/Maxcompute.md            |  2 +-
 docs/zh/connectors/source/Maxcompute.md            |  2 +-
 .../maxcompute/source/MaxcomputeSourceFactory.java |  5 +-
 .../maxcompute/MaxcomputeSourceFactoryTest.java    | 58 ++++++++++++++++++++++
 4 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/docs/en/connectors/source/Maxcompute.md 
b/docs/en/connectors/source/Maxcompute.md
index 472f602366..b50b10b3f5 100644
--- a/docs/en/connectors/source/Maxcompute.md
+++ b/docs/en/connectors/source/Maxcompute.md
@@ -68,7 +68,7 @@ for parallel reads.
 
 ### endpoint [string]
 
-`endpoint` Your Maxcompute endpoint start with http.
+Your MaxCompute endpoint, starting with `http`. This option is required and 
must not be an empty string or contain only whitespace. Blank values are 
rejected during configuration validation, before connecting to MaxCompute.
 
 ### project [string]
 
diff --git a/docs/zh/connectors/source/Maxcompute.md 
b/docs/zh/connectors/source/Maxcompute.md
index 1336f50b42..1529983e02 100644
--- a/docs/zh/connectors/source/Maxcompute.md
+++ b/docs/zh/connectors/source/Maxcompute.md
@@ -65,7 +65,7 @@ import ChangeLog from '../changelog/connector-maxcompute.md';
 
 ### endpoint [string]
 
-`endpoint` 您的 Maxcompute 端点,以 http 开头。
+您的 MaxCompute 端点,以 `http` 开头。此选项必填,不能是空字符串或仅包含空白字符。空白值会在配置校验阶段被拒绝,不会进入 
MaxCompute 连接阶段。
 
 ### project [string]
 
diff --git 
a/seatunnel-connectors-v2/connector-maxcompute/src/main/java/org/apache/seatunnel/connectors/seatunnel/maxcompute/source/MaxcomputeSourceFactory.java
 
b/seatunnel-connectors-v2/connector-maxcompute/src/main/java/org/apache/seatunnel/connectors/seatunnel/maxcompute/source/MaxcomputeSourceFactory.java
index 8859a9b42f..a682d607ee 100644
--- 
a/seatunnel-connectors-v2/connector-maxcompute/src/main/java/org/apache/seatunnel/connectors/seatunnel/maxcompute/source/MaxcomputeSourceFactory.java
+++ 
b/seatunnel-connectors-v2/connector-maxcompute/src/main/java/org/apache/seatunnel/connectors/seatunnel/maxcompute/source/MaxcomputeSourceFactory.java
@@ -17,6 +17,7 @@
 
 package org.apache.seatunnel.connectors.seatunnel.maxcompute.source;
 
+import org.apache.seatunnel.api.configuration.util.Conditions;
 import org.apache.seatunnel.api.configuration.util.OptionRule;
 import org.apache.seatunnel.api.options.ConnectorCommonOptions;
 import org.apache.seatunnel.api.options.table.CatalogOptions;
@@ -42,7 +43,9 @@ public class MaxcomputeSourceFactory implements 
TableSourceFactory {
     @Override
     public OptionRule optionRule() {
         return OptionRule.builder()
-                .required(MaxcomputeSourceOptions.ENDPOINT)
+                .required(
+                        MaxcomputeSourceOptions.ENDPOINT,
+                        Conditions.notBlank(MaxcomputeSourceOptions.ENDPOINT))
                 .optional(
                         MaxcomputeSourceOptions.ACCESS_ID,
                         MaxcomputeSourceOptions.ACCESS_KEY,
diff --git 
a/seatunnel-connectors-v2/connector-maxcompute/src/test/java/org/apache/seatunnel/connectors/seatunnel/maxcompute/MaxcomputeSourceFactoryTest.java
 
b/seatunnel-connectors-v2/connector-maxcompute/src/test/java/org/apache/seatunnel/connectors/seatunnel/maxcompute/MaxcomputeSourceFactoryTest.java
index ec0c5ea932..da7474c2fb 100644
--- 
a/seatunnel-connectors-v2/connector-maxcompute/src/test/java/org/apache/seatunnel/connectors/seatunnel/maxcompute/MaxcomputeSourceFactoryTest.java
+++ 
b/seatunnel-connectors-v2/connector-maxcompute/src/test/java/org/apache/seatunnel/connectors/seatunnel/maxcompute/MaxcomputeSourceFactoryTest.java
@@ -18,17 +18,75 @@
 package org.apache.seatunnel.connectors.seatunnel.maxcompute;
 
 import org.apache.seatunnel.api.configuration.Option;
+import org.apache.seatunnel.api.configuration.ReadonlyConfig;
+import org.apache.seatunnel.api.configuration.util.ConfigValidator;
 import org.apache.seatunnel.api.configuration.util.OptionRule;
+import org.apache.seatunnel.api.configuration.util.OptionValidationException;
+import 
org.apache.seatunnel.connectors.seatunnel.maxcompute.config.MaxcomputeSourceOptions;
 import 
org.apache.seatunnel.connectors.seatunnel.maxcompute.sink.MaxcomputeSinkFactory;
 import 
org.apache.seatunnel.connectors.seatunnel.maxcompute.source.MaxcomputeSourceFactory;
 
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 
+import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 
 public class MaxcomputeSourceFactoryTest {
+    @ParameterizedTest
+    @ValueSource(
+            strings = {
+                "http://service.odps.aliyun.com/api";,
+                " \thttp://service.odps.aliyun.com/api\r\n "
+            })
+    void acceptsNonblankEndpointWithoutTrimming(String endpoint) {
+        Map<String, Object> config = sourceConfig();
+        config.put(MaxcomputeSourceOptions.ENDPOINT.key(), endpoint);
+        ReadonlyConfig readonlyConfig = ReadonlyConfig.fromMap(config);
+
+        Assertions.assertDoesNotThrow(
+                () ->
+                        ConfigValidator.of(readonlyConfig)
+                                .validate(new 
MaxcomputeSourceFactory().optionRule()));
+        Assertions.assertEquals(endpoint, 
readonlyConfig.get(MaxcomputeSourceOptions.ENDPOINT));
+    }
+
+    @Test
+    void rejectsMissingEndpoint() {
+        Map<String, Object> config = sourceConfig();
+        config.remove(MaxcomputeSourceOptions.ENDPOINT.key());
+        assertInvalidEndpoint(config);
+    }
+
+    @ParameterizedTest
+    @ValueSource(strings = {"", " ", "\t", "\n", "\r", " \t\r\n "})
+    void rejectsBlankEndpoint(String endpoint) {
+        Map<String, Object> config = sourceConfig();
+        config.put(MaxcomputeSourceOptions.ENDPOINT.key(), endpoint);
+        assertInvalidEndpoint(config);
+    }
+
+    private Map<String, Object> sourceConfig() {
+        Map<String, Object> config = new HashMap<>();
+        config.put(MaxcomputeSourceOptions.ENDPOINT.key(), 
"http://service.odps.aliyun.com/api";);
+        config.put(MaxcomputeSourceOptions.TABLE_NAME.key(), "test_table");
+        return config;
+    }
+
+    private void assertInvalidEndpoint(Map<String, Object> config) {
+        OptionValidationException error =
+                Assertions.assertThrows(
+                        OptionValidationException.class,
+                        () ->
+                                
ConfigValidator.of(ReadonlyConfig.fromMap(config))
+                                        .validate(new 
MaxcomputeSourceFactory().optionRule()));
+        
Assertions.assertTrue(error.getMessage().contains(MaxcomputeSourceOptions.ENDPOINT.key()));
+    }
+
     @Test
     void optionRule() {
         Assertions.assertNotNull((new MaxcomputeSourceFactory()).optionRule());

Reply via email to