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

wanghailin 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 6468a1b53a [improve] add connector options class exist check (#8600)
6468a1b53a is described below

commit 6468a1b53a9196ba4cb78b4636fb449ecbaca204
Author: Jarvis <[email protected]>
AuthorDate: Thu Feb 6 11:35:23 2025 +0800

    [improve] add connector options class exist check (#8600)
---
 .../seatunnel/api/ConnectorOptionCheckTest.java    | 252 +++++++++++++++++++++
 1 file changed, 252 insertions(+)

diff --git 
a/seatunnel-ci-tools/src/test/java/org/apache/seatunnel/api/ConnectorOptionCheckTest.java
 
b/seatunnel-ci-tools/src/test/java/org/apache/seatunnel/api/ConnectorOptionCheckTest.java
new file mode 100644
index 0000000000..5c473ab7b2
--- /dev/null
+++ 
b/seatunnel-ci-tools/src/test/java/org/apache/seatunnel/api/ConnectorOptionCheckTest.java
@@ -0,0 +1,252 @@
+/*
+ * 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.api;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileVisitOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+@Slf4j
+public class ConnectorOptionCheckTest {
+
+    private static final String javaPathFragment =
+            "src" + File.separator + "main" + File.separator + "java";
+    private static final String JAVA_FILE_EXTENSION = ".java";
+    private static final String CONNECTOR_DIR = "seatunnel-connectors-v2";
+    private static final JavaParser JAVA_PARSER = new JavaParser();
+
+    @Test
+    public void checkConnectorOptionExist() {
+        Set<String> connectorOptionFileNames = new HashSet<>();
+        Set<String> whiteListConnectorOptionFileNames = buildWhiteList();
+        try (Stream<Path> paths = Files.walk(Paths.get(".."), 
FileVisitOption.FOLLOW_LINKS)) {
+            List<Path> connectorClassPaths =
+                    paths.filter(
+                                    path -> {
+                                        String pathString = path.toString();
+                                        return 
pathString.endsWith(JAVA_FILE_EXTENSION)
+                                                && 
pathString.contains(CONNECTOR_DIR)
+                                                && 
pathString.contains(javaPathFragment);
+                                    })
+                            .collect(Collectors.toList());
+            connectorClassPaths.forEach(
+                    path -> {
+                        try {
+                            ParseResult<CompilationUnit> parseResult =
+                                    
JAVA_PARSER.parse(Files.newInputStream(path));
+                            parseResult
+                                    .getResult()
+                                    .ifPresent(
+                                            compilationUnit -> {
+                                                
List<ClassOrInterfaceDeclaration> classes =
+                                                        
compilationUnit.findAll(
+                                                                
ClassOrInterfaceDeclaration.class);
+                                                for 
(ClassOrInterfaceDeclaration classDeclaration :
+                                                        classes) {
+                                                    if 
(classDeclaration.isAbstract()
+                                                            || 
classDeclaration.isInterface()) {
+                                                        continue;
+                                                    }
+                                                    
NodeList<ClassOrInterfaceType>
+                                                            implementedTypes =
+                                                                    
classDeclaration
+                                                                            
.getImplementedTypes();
+                                                    implementedTypes.forEach(
+                                                            implementedType -> 
{
+                                                                if 
(implementedType
+                                                                               
 .getNameAsString()
+                                                                               
 .equals(
+                                                                               
         "SeaTunnelSource")
+                                                                        || 
implementedType
+                                                                               
 .getNameAsString()
+                                                                               
 .equals(
+                                                                               
         "SeaTunnelSink")) {
+                                                                    
connectorOptionFileNames.add(
+                                                                            
path.getFileName()
+                                                                               
     .toString()
+                                                                               
     .replace(
+                                                                               
             JAVA_FILE_EXTENSION,
+                                                                               
             "")
+                                                                               
     .concat(
+                                                                               
             "Options"));
+                                                                }
+                                                            });
+                                                    
NodeList<ClassOrInterfaceType> extendedTypes =
+                                                            
classDeclaration.getExtendedTypes();
+                                                    extendedTypes.forEach(
+                                                            extendedType -> {
+                                                                if 
(extendedType
+                                                                               
 .getNameAsString()
+                                                                               
 .equals(
+                                                                               
         "AbstractSimpleSink")
+                                                                        || 
extendedType
+                                                                               
 .getNameAsString()
+                                                                               
 .equals(
+                                                                               
         "AbstractSingleSplitSource")
+                                                                        || 
extendedType
+                                                                               
 .getNameAsString()
+                                                                               
 .equals(
+                                                                               
         "IncrementalSource")) {
+                                                                    
connectorOptionFileNames.add(
+                                                                            
path.getFileName()
+                                                                               
     .toString()
+                                                                               
     .replace(
+                                                                               
             JAVA_FILE_EXTENSION,
+                                                                               
             "")
+                                                                               
     .concat(
+                                                                               
             "Options"));
+                                                                }
+                                                            });
+                                                }
+                                            });
+                        } catch (IOException e) {
+                            throw new RuntimeException(e);
+                        }
+                    });
+            connectorClassPaths.forEach(
+                    path -> {
+                        String className =
+                                
path.getFileName().toString().replace(JAVA_FILE_EXTENSION, "");
+                        connectorOptionFileNames.remove(className);
+                    });
+
+            whiteListConnectorOptionFileNames.forEach(
+                    whiteListConnectorOptionFileName -> {
+                        Assertions.assertTrue(
+                                
connectorOptionFileNames.remove(whiteListConnectorOptionFileName),
+                                "This [Options] class is in white list, but 
not found related connector classes, please check: ["
+                                        + whiteListConnectorOptionFileName
+                                        + "]\n");
+                    });
+
+            Assertions.assertEquals(
+                    0,
+                    connectorOptionFileNames.size(),
+                    () ->
+                            "Connector class does not have correspondingly 
[Options] class. "
+                                    + "The connector need put all parameter 
into <ConnectorClassName>Options classes, like [ActivemqSink] and 
[ActivemqSinkOptions].\n"
+                                    + "Those [Options] class are missing: \n"
+                                    + String.join("\n", 
connectorOptionFileNames)
+                                    + "\n");
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private Set<String> buildWhiteList() {
+        Set<String> whiteList = new HashSet<>();
+        whiteList.add("ElasticsearchSourceOptions");
+        whiteList.add("JdbcSinkOptions");
+        whiteList.add("TypesenseSourceOptions");
+        whiteList.add("RabbitmqSourceOptions");
+        whiteList.add("TypesenseSinkOptions");
+        whiteList.add("EmailSinkOptions");
+        whiteList.add("HudiSinkOptions");
+        whiteList.add("PulsarSinkOptions");
+        whiteList.add("HttpSinkOptions");
+        whiteList.add("SlsSinkOptions");
+        whiteList.add("DingTalkSinkOptions");
+        whiteList.add("Neo4jSinkOptions");
+        whiteList.add("SlackSinkOptions");
+        whiteList.add("MaxcomputeSinkOptions");
+        whiteList.add("PaimonSinkOptions");
+        whiteList.add("TDengineSourceOptions");
+        whiteList.add("PulsarSourceOptions");
+        whiteList.add("RedisSinkOptions");
+        whiteList.add("DruidSinkOptions");
+        whiteList.add("FakeSourceOptions");
+        whiteList.add("HbaseSinkOptions");
+        whiteList.add("MongodbSinkOptions");
+        whiteList.add("IoTDBSinkOptions");
+        whiteList.add("ActivemqSinkOptions");
+        whiteList.add("EasysearchSourceOptions");
+        whiteList.add("RabbitmqSinkOptions");
+        whiteList.add("StarRocksSourceOptions");
+        whiteList.add("AmazonSqsSinkOptions");
+        whiteList.add("IcebergSourceOptions");
+        whiteList.add("HbaseSourceOptions");
+        whiteList.add("PaimonSourceOptions");
+        whiteList.add("IoTDBSourceOptions");
+        whiteList.add("SlsSourceOptions");
+        whiteList.add("SentrySinkOptions");
+        whiteList.add("EasysearchSinkOptions");
+        whiteList.add("QdrantSinkOptions");
+        whiteList.add("ElasticsearchSinkOptions");
+        whiteList.add("MilvusSourceOptions");
+        whiteList.add("RocketMqSinkOptions");
+        whiteList.add("ClickhouseFileSinkOptions");
+        whiteList.add("IcebergSinkOptions");
+        whiteList.add("KafkaSourceOptions");
+        whiteList.add("AssertSinkOptions");
+        whiteList.add("MaxcomputeSourceOptions");
+        whiteList.add("InfluxDBSourceOptions");
+        whiteList.add("InfluxDBSinkOptions");
+        whiteList.add("CassandraSinkOptions");
+        whiteList.add("KuduSourceOptions");
+        whiteList.add("SocketSinkOptions");
+        whiteList.add("DataHubSinkOptions");
+        whiteList.add("ClickhouseSinkOptions");
+        whiteList.add("SelectDBSinkOptions");
+        whiteList.add("ConsoleSinkOptions");
+        whiteList.add("PrometheusSinkOptions");
+        whiteList.add("FirestoreSinkOptions");
+        whiteList.add("ClickhouseSourceOptions");
+        whiteList.add("MilvusSinkOptions");
+        whiteList.add("RocketMqSourceOptions");
+        whiteList.add("TablestoreSinkOptions");
+        whiteList.add("TableStoreDBSourceOptions");
+        whiteList.add("AmazonDynamoDBSinkOptions");
+        whiteList.add("KuduSinkOptions");
+        whiteList.add("KafkaSinkOptions");
+        whiteList.add("TDengineSinkOptions");
+        whiteList.add("Neo4jSourceOptions");
+        whiteList.add("HttpSourceOptions");
+        whiteList.add("QdrantSourceOptions");
+        whiteList.add("SheetsSourceOptions");
+        whiteList.add("SocketSourceOptions");
+        whiteList.add("OpenMldbSourceOptions");
+        whiteList.add("Web3jSourceOptions");
+        whiteList.add("CassandraSourceOptions");
+        whiteList.add("RedisSourceOptions");
+        whiteList.add("PostgresIncrementalSourceOptions");
+        whiteList.add("SqlServerIncrementalSourceOptions");
+        whiteList.add("OracleIncrementalSourceOptions");
+        whiteList.add("MySqlIncrementalSourceOptions");
+        whiteList.add("MongodbIncrementalSourceOptions");
+        return whiteList;
+    }
+}

Reply via email to