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

chl-wxp 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 0e2f4ef8d5 [Fix][API] Add missing OptionRule validation for 
CatalogFactory creation path (#11127)
0e2f4ef8d5 is described below

commit 0e2f4ef8d57000df40bfc2a3f32c635fe632b6c0
Author: zhiwei.niu <[email protected]>
AuthorDate: Mon Jun 22 10:25:40 2026 +0800

    [Fix][API] Add missing OptionRule validation for CatalogFactory creation 
path (#11127)
---
 .../seatunnel/api/table/factory/FactoryUtil.java   |  8 ++-
 .../api/table/catalog/CatalogTableUtilTest.java    | 66 ++++++++++++++++++++++
 .../jdbc/catalog/duckdb/DuckDBCatalogFactory.java  | 12 +++-
 .../lance/catalog/LanceCatalogFactory.java         |  2 +-
 4 files changed, 84 insertions(+), 4 deletions(-)

diff --git 
a/seatunnel-api/src/main/java/org/apache/seatunnel/api/table/factory/FactoryUtil.java
 
b/seatunnel-api/src/main/java/org/apache/seatunnel/api/table/factory/FactoryUtil.java
index 8412bc60ce..a4f078db0c 100644
--- 
a/seatunnel-api/src/main/java/org/apache/seatunnel/api/table/factory/FactoryUtil.java
+++ 
b/seatunnel-api/src/main/java/org/apache/seatunnel/api/table/factory/FactoryUtil.java
@@ -286,13 +286,17 @@ public final class FactoryUtil {
 
     public static Optional<Catalog> createOptionalCatalog(
             String catalogName,
-            ReadonlyConfig options,
+            ReadonlyConfig readonlyConfig,
             ClassLoader classLoader,
             String factoryIdentifier) {
         Optional<CatalogFactory> optionalFactory =
                 discoverOptionalFactory(classLoader, CatalogFactory.class, 
factoryIdentifier);
+
         return optionalFactory.map(
-                catalogFactory -> catalogFactory.createCatalog(catalogName, 
options));
+                catalogFactory -> {
+                    
ConfigValidator.of(readonlyConfig).validate(catalogFactory.optionRule());
+                    return catalogFactory.createCatalog(catalogName, 
readonlyConfig);
+                });
     }
 
     public static <T extends Factory> URL getFactoryUrl(T factory) {
diff --git 
a/seatunnel-api/src/test/java/org/apache/seatunnel/api/table/catalog/CatalogTableUtilTest.java
 
b/seatunnel-api/src/test/java/org/apache/seatunnel/api/table/catalog/CatalogTableUtilTest.java
index 73a6b3d47d..e9cd815f27 100644
--- 
a/seatunnel-api/src/test/java/org/apache/seatunnel/api/table/catalog/CatalogTableUtilTest.java
+++ 
b/seatunnel-api/src/test/java/org/apache/seatunnel/api/table/catalog/CatalogTableUtilTest.java
@@ -22,7 +22,9 @@ import 
org.apache.seatunnel.shade.com.typesafe.config.ConfigFactory;
 import org.apache.seatunnel.shade.com.typesafe.config.ConfigValueFactory;
 
 import org.apache.seatunnel.api.configuration.ReadonlyConfig;
+import org.apache.seatunnel.api.configuration.util.OptionValidationException;
 import org.apache.seatunnel.api.options.ConnectorCommonOptions;
+import org.apache.seatunnel.api.table.factory.FactoryUtil;
 import org.apache.seatunnel.api.table.type.ArrayType;
 import org.apache.seatunnel.api.table.type.BasicType;
 import org.apache.seatunnel.api.table.type.DecimalType;
@@ -43,7 +45,10 @@ import java.net.URL;
 import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.Optional;
 
 import static 
org.apache.seatunnel.common.constants.CollectionConstants.PLUGIN_NAME;
 
@@ -208,4 +213,65 @@ public class CatalogTableUtilTest {
         }
         return Paths.get(resource.toURI()).toString();
     }
+
+    @Test
+    void createOptionalCatalogWithValidConfig() {
+        Map<String, Object> configMap = new HashMap<>();
+        configMap.put("username", "admin");
+        configMap.put("password", "secret");
+        ReadonlyConfig config = ReadonlyConfig.fromMap(configMap);
+
+        Optional<Catalog> catalog =
+                FactoryUtil.createOptionalCatalog(
+                        "test", config, 
Thread.currentThread().getContextClassLoader(), "InMemory");
+
+        Assertions.assertTrue(catalog.isPresent());
+    }
+
+    @Test
+    void createOptionalCatalogWithMissingRequiredOptionsThrows() {
+        Map<String, Object> configMap = new HashMap<>();
+        configMap.put("host", "localhost");
+        ReadonlyConfig config = ReadonlyConfig.fromMap(configMap);
+
+        Assertions.assertThrows(
+                OptionValidationException.class,
+                () ->
+                        FactoryUtil.createOptionalCatalog(
+                                "test",
+                                config,
+                                Thread.currentThread().getContextClassLoader(),
+                                "InMemory"));
+    }
+
+    @Test
+    void createOptionalCatalogWithPartialRequiredOptionsThrows() {
+        Map<String, Object> configMap = new HashMap<>();
+        configMap.put("username", "admin");
+        ReadonlyConfig config = ReadonlyConfig.fromMap(configMap);
+
+        Assertions.assertThrows(
+                OptionValidationException.class,
+                () ->
+                        FactoryUtil.createOptionalCatalog(
+                                "test",
+                                config,
+                                Thread.currentThread().getContextClassLoader(),
+                                "InMemory"));
+    }
+
+    @Test
+    void createOptionalCatalogWithUnknownFactoryReturnsEmpty() {
+        Map<String, Object> configMap = new HashMap<>();
+        ReadonlyConfig config = ReadonlyConfig.fromMap(configMap);
+
+        Optional<Catalog> catalog =
+                FactoryUtil.createOptionalCatalog(
+                        "test",
+                        config,
+                        Thread.currentThread().getContextClassLoader(),
+                        "NonExistentFactory");
+
+        Assertions.assertFalse(catalog.isPresent());
+    }
 }
diff --git 
a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/duckdb/DuckDBCatalogFactory.java
 
b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/duckdb/DuckDBCatalogFactory.java
index 1e966111e7..53999ace8f 100644
--- 
a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/duckdb/DuckDBCatalogFactory.java
+++ 
b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/duckdb/DuckDBCatalogFactory.java
@@ -28,6 +28,13 @@ import 
org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.DatabaseI
 
 import com.google.auto.service.AutoService;
 
+import static 
org.apache.seatunnel.connectors.seatunnel.jdbc.config.JdbcCommonOptions.DECIMAL_TYPE_NARROWING;
+import static 
org.apache.seatunnel.connectors.seatunnel.jdbc.config.JdbcCommonOptions.HANDLE_BLOB_AS_STRING;
+import static 
org.apache.seatunnel.connectors.seatunnel.jdbc.config.JdbcCommonOptions.PASSWORD;
+import static 
org.apache.seatunnel.connectors.seatunnel.jdbc.config.JdbcCommonOptions.SCHEMA;
+import static 
org.apache.seatunnel.connectors.seatunnel.jdbc.config.JdbcCommonOptions.URL;
+import static 
org.apache.seatunnel.connectors.seatunnel.jdbc.config.JdbcCommonOptions.USERNAME;
+
 /** Factory for {@link DuckDBCatalog} */
 @AutoService(Factory.class)
 public class DuckDBCatalogFactory implements CatalogFactory {
@@ -50,6 +57,9 @@ public class DuckDBCatalogFactory implements CatalogFactory {
 
     @Override
     public OptionRule optionRule() {
-        return JdbcCommonOptions.BASE_CATALOG_RULE.build();
+        return OptionRule.builder()
+                .required(URL)
+                .optional(USERNAME, PASSWORD, SCHEMA, DECIMAL_TYPE_NARROWING, 
HANDLE_BLOB_AS_STRING)
+                .build();
     }
 }
diff --git 
a/seatunnel-connectors-v2/connector-lance/src/main/java/org/apache/seatunnel/connectors/seatunnel/lance/catalog/LanceCatalogFactory.java
 
b/seatunnel-connectors-v2/connector-lance/src/main/java/org/apache/seatunnel/connectors/seatunnel/lance/catalog/LanceCatalogFactory.java
index 4235a141a4..7d26b4e8ef 100644
--- 
a/seatunnel-connectors-v2/connector-lance/src/main/java/org/apache/seatunnel/connectors/seatunnel/lance/catalog/LanceCatalogFactory.java
+++ 
b/seatunnel-connectors-v2/connector-lance/src/main/java/org/apache/seatunnel/connectors/seatunnel/lance/catalog/LanceCatalogFactory.java
@@ -35,6 +35,6 @@ public class LanceCatalogFactory implements CatalogFactory {
 
     @Override
     public OptionRule optionRule() {
-        return null;
+        return OptionRule.builder().build();
     }
 }

Reply via email to