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

davidzollo 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 8b28ff8e7c [Improve][Connector-V2] Validate SelectDB Cloud required 
options (#12351)
8b28ff8e7c is described below

commit 8b28ff8e7c6a5105e033909ba53b152df0289255
Author: Nikhil kumar <[email protected]>
AuthorDate: Tue Sep 29 20:46:57 2026 +0530

    [Improve][Connector-V2] Validate SelectDB Cloud required options (#12351)
---
 docs/en/connectors/sink/SelectDB-Cloud.md          |  14 +--
 docs/zh/connectors/sink/SelectDB-Cloud.md          |  14 +--
 .../selectdb/sink/SelectDBSinkFactory.java         |  13 ++-
 .../selectdb/sink/SelectDBSinkFactoryTest.java     | 110 +++++++++++++++++++++
 4 files changed, 133 insertions(+), 18 deletions(-)

diff --git a/docs/en/connectors/sink/SelectDB-Cloud.md 
b/docs/en/connectors/sink/SelectDB-Cloud.md
index 337288cefe..80a7daa733 100644
--- a/docs/en/connectors/sink/SelectDB-Cloud.md
+++ b/docs/en/connectors/sink/SelectDB-Cloud.md
@@ -35,13 +35,13 @@ Version Supported
 
 |        Name        |  Type  | Required |        Default         |            
                                                                                
                                                                        
Description                                                                     
                                                                                
               |
 
|--------------------|--------|----------|------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| load-url           | String | Yes      | -                      | `SelectDB 
Cloud` warehouse http address, the format is `warehouse_ip:http_port`           
                                                                                
                                                                                
                                                                                
        |
-| jdbc-url           | String | Yes      | -                      | `SelectDB 
Cloud` warehouse jdbc address, the format is `warehouse_ip:mysql_port`          
                                                                                
                                                                                
                                                                                
        |
-| cluster-name       | String | Yes      | -                      | `SelectDB 
Cloud` cluster name                                                             
                                                                                
                                                                                
                                                                                
        |
-| username           | String | Yes      | -                      | `SelectDB 
Cloud` user username                                                            
                                                                                
                                                                                
                                                                                
        |
-| password           | String | Yes      | -                      | `SelectDB 
Cloud` user password                                                            
                                                                                
                                                                                
                                                                                
        |
+| load-url           | String | Yes      | -                      | `SelectDB 
Cloud` warehouse HTTP address, in the format `warehouse_ip:http_port`. Must not 
be empty or whitespace-only.                                                    
                                                                                
                                                                                
        |
+| jdbc-url           | String | Yes      | -                      | `SelectDB 
Cloud` warehouse JDBC address, in the format `warehouse_ip:mysql_port`. Must 
not be empty or whitespace-only.                                                
                                                                                
                                                                                
           |
+| cluster-name       | String | Yes      | -                      | `SelectDB 
Cloud` cluster name. Must not be empty or whitespace-only.                      
                                                                                
                                                                                
                                                                                
         |
+| username           | String | Yes      | -                      | `SelectDB 
Cloud` username. Must not be empty or whitespace-only.                          
                                                                                
                                                                                
                                                                                
         |
+| password           | String | No       | -                      | Optional 
`SelectDB Cloud` user password.                                                 
                                                                                
                                                                                
                                                                                
         |
 | sink.enable-2pc    | bool   | No       | true                   | Whether to 
enable two-phase commit (2pc), the default is true, to ensure Exactly-Once 
semantics. SelectDB uses cache files to load data. When the amount of data is 
large, cached data may become invalid (the default expiration time is 1 hour). 
If you encounter a large amount of data write loss, please configure 
sink.enable-2pc to false. |
-| table.identifier   | String | Yes      | -                      | The name 
of `SelectDB Cloud` table, the format is `database.table`                       
                                                                                
                                                                                
                                                                                
         |
+| table.identifier   | String | Yes      | -                      | The name 
of the `SelectDB Cloud` table, in the format `database.table`. Must not be 
empty or whitespace-only.                                                       
                                                                                
                                                                                
              |
 | sink.enable-delete | bool   | No       | false                  | Whether to 
enable deletion. This option requires SelectDB Cloud table to enable batch 
delete function, and only supports Unique model.                                
                                                                                
                                                                                
            |
 | sink.max-retries   | int    | No       | 3                      | the max 
retry times if writing records to database failed                               
                                                                                
                                                                                
                                                                                
          |
 | sink.buffer-size   | int    | No       | 10 * 1024 * 1024 (10MB) | the 
buffer size to cache data for stream load.                                      
                                                                                
                                                                                
                                                                                
              |
@@ -176,4 +176,4 @@ sink {
 
 ## Changelog
 
-<ChangeLog />
\ No newline at end of file
+<ChangeLog />
diff --git a/docs/zh/connectors/sink/SelectDB-Cloud.md 
b/docs/zh/connectors/sink/SelectDB-Cloud.md
index 83f57ba7e8..23ec152f22 100644
--- a/docs/zh/connectors/sink/SelectDB-Cloud.md
+++ b/docs/zh/connectors/sink/SelectDB-Cloud.md
@@ -36,13 +36,13 @@ SelectDB Cloud 接收器连接器的内部实现是在批量缓存后上传数
 
 |        名称        |  类型  | 是否必填 |        默认值         |                        
                                                                                
                                                            描述                  
                                                                                
                                                                  |
 
|--------------------|--------|----------|------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| load-url           | String | 是       | -                      | `SelectDB 
Cloud` 仓库的 HTTP 地址,格式为 `warehouse_ip:http_port`                                 
                                                                                
                                                                                
                                                                         |
-| jdbc-url           | String | 是       | -                      | `SelectDB 
Cloud` 仓库的 JDBC 地址,格式为 `warehouse_ip:mysql_port`                                
                                                                                
                                                                                
                                                                         |
-| cluster-name       | String | 是       | -                      | `SelectDB 
Cloud` 集群名称                                                                     
                                                                                
                                                                                
                                                                             |
-| username           | String | 是       | -                      | `SelectDB 
Cloud` 用户名                                                                      
                                                                                
                                                                                
                                                                              |
-| password           | String | 是       | -                      | `SelectDB 
Cloud` 用户密码                                                                     
                                                                                
                                                                                
                                                                             |
+| load-url           | String | 是       | -                      | `SelectDB 
Cloud` 仓库的 HTTP 地址,格式为 `warehouse_ip:http_port`。值不能为空或仅包含空白字符。                  
                                                                                
                                                                                
                                                           |
+| jdbc-url           | String | 是       | -                      | `SelectDB 
Cloud` 仓库的 JDBC 地址,格式为 `warehouse_ip:mysql_port`。值不能为空或仅包含空白字符。                 
                                                                                
                                                                                
                                                           |
+| cluster-name       | String | 是       | -                      | `SelectDB 
Cloud` 集群名称。值不能为空或仅包含空白字符。                                                      
                                                                                
                                                                                
                                                              |
+| username           | String | 是       | -                      | `SelectDB 
Cloud` 用户名。值不能为空或仅包含空白字符。                                                       
                                                                                
                                                                                
                                                               |
+| password           | String | 否       | -                      | 可选的 
`SelectDB Cloud` 用户密码。                                                          
                                                                                
                                                                                
                                                                               |
 | sink.enable-2pc    | bool   | 否       | true                   | 
是否启用两阶段提交(2pc),默认为 true,以确保 Exactly-Once 语义。SelectDB 
使用缓存文件加载数据。当数据量较大时,缓存数据可能会失效(默认过期时间为 1 小时)。如果遇到大量数据写入丢失的情况,请将 sink.enable-2pc 
配置为 false。                                                                      
                                     |
-| table.identifier   | String | 是       | -                      | `SelectDB 
Cloud` 表的名称,格式为 `database.table`                                                
                                                                                
                                                                                
                                                                          |
+| table.identifier   | String | 是       | -                      | `SelectDB 
Cloud` 表的名称,格式为 `database.table`。值不能为空或仅包含空白字符。                                 
                                                                                
                                                                                
                                                           |
 | sink.enable-delete | bool   | 否       | false                  | 
是否启用删除功能。此选项要求 SelectDB Cloud 表启用批量删除功能,并且仅支持 Unique 模型。                        
                                                                                
                                                                                
                                                             |
 | sink.max-retries   | int   | 否       | 3                      | 
写入数据库失败时的最大重试次数                                                                 
                                                                                
                                                                                
                                                                            |
 | sink.buffer-size   | int   | 否       | 10 * 1024 * 1024 (10MB) | 
用于流式加载的数据缓存缓冲区大小                                                                
                                                                                
                                                                                
                                                                           |
@@ -177,4 +177,4 @@ sink {
 
 ## 变更日志
 
-<ChangeLog />
\ No newline at end of file
+<ChangeLog />
diff --git 
a/seatunnel-connectors-v2/connector-selectdb-cloud/src/main/java/org/apache/seatunnel/connectors/selectdb/sink/SelectDBSinkFactory.java
 
b/seatunnel-connectors-v2/connector-selectdb-cloud/src/main/java/org/apache/seatunnel/connectors/selectdb/sink/SelectDBSinkFactory.java
index 289a9406ec..1e08a24743 100644
--- 
a/seatunnel-connectors-v2/connector-selectdb-cloud/src/main/java/org/apache/seatunnel/connectors/selectdb/sink/SelectDBSinkFactory.java
+++ 
b/seatunnel-connectors-v2/connector-selectdb-cloud/src/main/java/org/apache/seatunnel/connectors/selectdb/sink/SelectDBSinkFactory.java
@@ -26,6 +26,8 @@ import 
org.apache.seatunnel.connectors.selectdb.config.SelectDBSinkOptions;
 
 import com.google.auto.service.AutoService;
 
+import static org.apache.seatunnel.api.configuration.util.Conditions.notBlank;
+
 @AutoService(Factory.class)
 public class SelectDBSinkFactory implements TableSinkFactory {
 
@@ -37,12 +39,15 @@ public class SelectDBSinkFactory implements 
TableSinkFactory {
     @Override
     public OptionRule optionRule() {
         return OptionRule.builder()
+                .required(SelectDBSinkOptions.JDBC_URL, 
notBlank(SelectDBSinkOptions.JDBC_URL))
+                .required(SelectDBSinkOptions.LOAD_URL, 
notBlank(SelectDBSinkOptions.LOAD_URL))
                 .required(
-                        SelectDBSinkOptions.JDBC_URL,
-                        SelectDBSinkOptions.LOAD_URL,
                         SelectDBSinkOptions.CLUSTER_NAME,
-                        SelectDBSinkOptions.USERNAME,
-                        SelectDBSinkOptions.TABLE_IDENTIFIER)
+                        notBlank(SelectDBSinkOptions.CLUSTER_NAME))
+                .required(SelectDBSinkOptions.USERNAME, 
notBlank(SelectDBSinkOptions.USERNAME))
+                .required(
+                        SelectDBSinkOptions.TABLE_IDENTIFIER,
+                        notBlank(SelectDBSinkOptions.TABLE_IDENTIFIER))
                 .optional(
                         SelectDBSinkOptions.PASSWORD,
                         SelectDBSinkOptions.SINK_ENABLE_2PC,
diff --git 
a/seatunnel-connectors-v2/connector-selectdb-cloud/src/test/java/org/apache/seatunnel/connectors/selectdb/sink/SelectDBSinkFactoryTest.java
 
b/seatunnel-connectors-v2/connector-selectdb-cloud/src/test/java/org/apache/seatunnel/connectors/selectdb/sink/SelectDBSinkFactoryTest.java
new file mode 100644
index 0000000000..260d7a764a
--- /dev/null
+++ 
b/seatunnel-connectors-v2/connector-selectdb-cloud/src/test/java/org/apache/seatunnel/connectors/selectdb/sink/SelectDBSinkFactoryTest.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.connectors.selectdb.sink;
+
+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.selectdb.config.SelectDBSinkOptions;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+class SelectDBSinkFactoryTest {
+
+    private static final OptionRule OPTION_RULE = new 
SelectDBSinkFactory().optionRule();
+    private static final List<String> REQUIRED_STRING_KEYS =
+            Arrays.asList(
+                    SelectDBSinkOptions.JDBC_URL.key(),
+                    SelectDBSinkOptions.LOAD_URL.key(),
+                    SelectDBSinkOptions.CLUSTER_NAME.key(),
+                    SelectDBSinkOptions.USERNAME.key(),
+                    SelectDBSinkOptions.TABLE_IDENTIFIER.key());
+
+    @Test
+    void testValidConfiguration() {
+        Assertions.assertDoesNotThrow(() -> validate(validConfig()));
+
+        Map<String, Object> valuesWithSurroundingSpaces = validConfig();
+        for (String key : REQUIRED_STRING_KEYS) {
+            valuesWithSurroundingSpaces.put(key, " " + 
valuesWithSurroundingSpaces.get(key) + " ");
+        }
+        Assertions.assertDoesNotThrow(() -> 
validate(valuesWithSurroundingSpaces));
+    }
+
+    @Test
+    void testMissingRequiredStringsRejected() {
+        for (String key : REQUIRED_STRING_KEYS) {
+            Map<String, Object> config = validConfig();
+            config.remove(key);
+
+            Assertions.assertThrows(OptionValidationException.class, () -> 
validate(config), key);
+        }
+    }
+
+    @Test
+    void testEmptyRequiredStringsRejected() {
+        assertRequiredStringsRejected("");
+    }
+
+    @Test
+    void testWhitespaceOnlyRequiredStringsRejected() {
+        assertRequiredStringsRejected("  \t");
+    }
+
+    @Test
+    void testPasswordRemainsOptional() {
+        Assertions.assertDoesNotThrow(() -> validate(validConfig()));
+
+        Map<String, Object> emptyPassword = validConfig();
+        emptyPassword.put(SelectDBSinkOptions.PASSWORD.key(), "");
+        Assertions.assertDoesNotThrow(() -> validate(emptyPassword));
+    }
+
+    private void assertRequiredStringsRejected(String value) {
+        for (String key : REQUIRED_STRING_KEYS) {
+            Map<String, Object> config = validConfig();
+            config.put(key, value);
+
+            Assertions.assertThrows(OptionValidationException.class, () -> 
validate(config), key);
+        }
+    }
+
+    private void validate(Map<String, Object> config) {
+        ReadonlyConfig readonlyConfig = ReadonlyConfig.fromMap(config);
+        ConfigValidator.validateUnknownKeys(
+                readonlyConfig, OPTION_RULE, SelectDBSinkOptions.IDENTIFIER);
+        ConfigValidator.of(readonlyConfig).validate(OPTION_RULE);
+    }
+
+    private Map<String, Object> validConfig() {
+        Map<String, Object> config = new HashMap<>();
+        config.put(SelectDBSinkOptions.JDBC_URL.key(), 
"selectdb.example.com:9030");
+        config.put(SelectDBSinkOptions.LOAD_URL.key(), 
"selectdb.example.com:8080");
+        config.put(SelectDBSinkOptions.CLUSTER_NAME.key(), "selectdb-cluster");
+        config.put(SelectDBSinkOptions.USERNAME.key(), "selectdb-user");
+        config.put(SelectDBSinkOptions.TABLE_IDENTIFIER.key(), 
"database.table");
+        return config;
+    }
+}

Reply via email to