shangeyao commented on code in PR #4419:
URL: https://github.com/apache/streampark/pull/4419#discussion_r3540610888


##########
streampark-common/src/main/java/org/apache/streampark/common/util/Utils.java:
##########
@@ -0,0 +1,243 @@
+/*
+ * 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.streampark.common.util;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.streampark.shaded.org.slf4j.Logger;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.Flushable;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.time.Duration;
+import java.time.LocalDateTime;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Properties;
+import java.util.UUID;
+import java.util.concurrent.locks.LockSupport;
+import java.util.jar.JarFile;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+/** General utility methods. */
+public final class Utils {
+
+    private static final Logger LOG =
+            
StreamParkLoggerFactory.loggerFactory().getLogger(Utils.class.getName());
+
+    private static final String OS = 
System.getProperty("os.name").toLowerCase();
+
+    private Utils() {}
+
+    public static boolean isNotEmpty(Object elem) {
+        if (elem == null) {
+            return false;
+        }
+        if (elem instanceof Object[]) {
+            return ((Object[]) elem).length > 0;
+        }
+        if (elem instanceof CharSequence) {
+            return elem.toString().trim().length() > 0;
+        }
+        if (elem instanceof Collection) {
+            return !((Collection<?>) elem).isEmpty();
+        }
+        if (elem instanceof Iterable) {
+            return ((Iterable<?>) elem).iterator().hasNext();
+        }
+        if (elem instanceof Map) {
+            return !((Map<?, ?>) elem).isEmpty();
+        }
+        return true;
+    }
+
+    public static boolean isEmpty(Object elem) {
+        return !isNotEmpty(elem);
+    }
+
+    public static String uuid() {
+        return UUID.randomUUID().toString().replaceAll("-", "");
+    }
+
+    public static void requireCheckJarFile(URL jar) throws IOException {
+        File jarFile;
+        try {
+            jarFile = new File(jar.toURI());
+        } catch (Exception e) {
+            throw new IOException("JAR file path is invalid " + jar, e);
+        }
+        if (!jarFile.exists()) {
+            throw new IOException("JAR file does not exist '" + 
jarFile.getAbsolutePath() + "'");
+        }
+        if (!jarFile.canRead()) {
+            throw new IOException("JAR file can't be read '" + 
jarFile.getAbsolutePath() + "'");
+        }
+        try (JarFile jf = new JarFile(jarFile)) {
+            // verify jar is readable
+        } catch (IOException e) {
+            throw new IOException(
+                    "Error while opening jar file '" + 
jarFile.getAbsolutePath() + "'", e);
+        }
+    }
+
+    public static Manifest getJarManifest(File jarFile) throws IOException {
+        requireCheckJarFile(jarFile.toURI().toURL());
+        return AutoCloseUtils.using(
+                new JarInputStream(new BufferedInputStream(new 
FileInputStream(jarFile))),

Review Comment:
   Fixed in `752fa8a68`: `SafePathUtils` co-locates `Path.resolve()` validation 
with file I/O.



##########
streampark-common/src/main/java/org/apache/streampark/common/util/FileUtils.java:
##########
@@ -0,0 +1,299 @@
+/*
+ * 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.streampark.common.util;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
+import java.io.Serializable;
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Scanner;
+import java.util.stream.Collectors;
+
+public final class FileUtils {
+
+    private FileUtils() {}
+
+    private static String bytesToHexString(byte[] src) {
+        if (src == null || src.length <= 0) {
+            return null;
+        }
+        StringBuilder stringBuilder = new StringBuilder();
+        for (byte b : src) {
+            int v = b & 0xFF;
+            String hv = Integer.toHexString(v).toUpperCase();
+            if (hv.length() < 2) {
+                stringBuilder.append(0);
+            }
+            stringBuilder.append(hv);
+        }
+        return stringBuilder.toString();
+    }
+
+    public static boolean isJarFileType(InputStream input) {
+        if (input == null) {
+            throw new RuntimeException("The inputStream can not be null");
+        }
+        return AutoCloseUtils.using(
+                        input,
+                        in -> {
+                            byte[] b = new byte[4];
+                            try {
+                                in.read(b, 0, b.length);
+                            } catch (IOException e) {
+                                throw new RuntimeException(e);
+                            }
+                            return bytesToHexString(b);
+                        })
+                .equals("504B0304");
+    }
+
+    public static boolean isJarFileType(File file) throws IOException {
+        if (!file.exists() || !file.isFile()) {
+            throw new RuntimeException("The file does not exist or the path is 
a directory");
+        }
+        return isJarFileType(new FileInputStream(file));
+    }
+
+    public static File createTempDir() {
+        final int TEMP_DIR_ATTEMPTS = 10000;
+        File baseDir = new File(System.getProperty("java.io.tmpdir"));
+        String baseName = System.currentTimeMillis() + "-";
+        for (int counter = 0; counter < TEMP_DIR_ATTEMPTS; counter++) {
+            File tempDir = new File(baseDir, baseName + counter);
+            if (tempDir.mkdir()) {
+                return tempDir;
+            }
+        }
+        throw new IllegalStateException(
+                "[StreamPark] Failed to create directory within "
+                        + TEMP_DIR_ATTEMPTS
+                        + "  attempts (tried "
+                        + baseName
+                        + " 0 to "
+                        + baseName
+                        + (TEMP_DIR_ATTEMPTS - 1)
+                        + ")");
+    }
+
+    public static void mkdir(File dir) throws IOException {
+        if (dir.exists() && !dir.isDirectory()) {
+            throw new IOException("File " + dir + " exists and is not a 
directory. Unable to create directory.");
+        } else if (!dir.mkdirs() && !dir.isDirectory()) {
+            throw new IOException("Unable to create directory " + dir);
+        }
+    }
+
+    public static String getPathFromEnv(String env) {
+        String path = System.getenv(env);
+        if (path == null) {
+            path = System.getProperty(env);
+        }
+        AssertUtils.notNull(path, "[StreamPark] FileUtils.getPathFromEnv: " + 
env + " is not set on system env");
+        File file = new File(path);
+        if (!file.exists()) {
+            throw new IllegalArgumentException("[StreamPark] 
FileUtils.getPathFromEnv: " + env + " is not exist!");
+        }
+        return file.getAbsolutePath();
+    }
+
+    public static String resolvePath(String parent, String child) {
+        File file = new File(parent, child);
+        if (!file.exists()) {
+            throw new IllegalArgumentException(
+                    "[StreamPark] FileUtils.resolvePath: " + 
file.getAbsolutePath() + " is not exist!");
+        }
+        return file.getAbsolutePath();
+    }
+
+    public static String getSuffix(String filename) {
+        AssertUtils.notNull(filename);
+        return filename.substring(filename.lastIndexOf("."));
+    }
+
+    public static List<URL> listFileAsURL(String dirPath) {
+        File dir = new File(dirPath);
+        if (dir.exists() && dir.isDirectory()) {
+            File[] files = dir.listFiles();
+            if (files != null && files.length > 0) {
+                List<URL> urls = new ArrayList<>();
+                for (File f : files) {
+                    try {
+                        urls.add(f.toURI().toURL());
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+                return urls;
+            }
+        }
+        return Collections.emptyList();
+    }
+
+    public static boolean exists(Serializable file) {
+        if (file == null) {
+            return false;
+        }
+        if (file instanceof File) {
+            return ((File) file).exists();
+        }
+        return new File(file.toString()).exists();
+    }
+
+    public static boolean directoryNotBlank(Serializable file) {
+        if (file == null) {
+            return false;
+        }
+        File f = file instanceof File ? (File) file : new 
File(file.toString());
+        String[] list = f.list();
+        return f.isDirectory() && list != null && list.length > 0;
+    }
+
+    public static boolean equals(File file1, File file2) throws IOException {
+        if (file1 == null || file2 == null) {
+            return false;
+        }
+        if (!file1.exists() || !file2.exists()) {
+            return false;
+        }
+        if (file1.getAbsolutePath().equals(file2.getAbsolutePath())) {
+            return true;
+        }
+        BufferedInputStream first = new BufferedInputStream(new 
FileInputStream(file1));
+        BufferedInputStream second = new BufferedInputStream(new 
FileInputStream(file2));
+        if (first.available() != second.available()) {
+            Utils.close(first, second);
+            return false;
+        }
+        while (true) {
+            int firRead = first.read();
+            int secRead = second.read();
+            if (firRead != secRead) {
+                Utils.close(first, second);
+                return false;
+            }
+            if (firRead == -1) {
+                Utils.close(first, second);
+                return true;
+            }
+        }
+    }
+
+    public static void readInputStream(InputStream in, byte[] array) throws 
IOException {
+        try (InputStream input = in) {
+            int toRead = array.length;
+            int off = 0;
+            while (toRead > 0) {
+                int ret = input.read(array, off, toRead);
+                if (ret < 0) {
+                    throw new IOException("Bad inputStream, premature EOF");
+                }
+                toRead -= ret;
+                off += ret;
+            }
+        }
+    }
+
+    public static String readFile(File file) throws IOException {
+        if (file.length() >= Integer.MAX_VALUE) {

Review Comment:
   Fixed in `752fa8a68`: `SafePathUtils` co-locates `Path.resolve()` validation 
with file I/O.



##########
streampark-common/src/main/java/org/apache/streampark/common/util/FileUtils.java:
##########
@@ -0,0 +1,299 @@
+/*
+ * 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.streampark.common.util;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
+import java.io.Serializable;
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Scanner;
+import java.util.stream.Collectors;
+
+public final class FileUtils {
+
+    private FileUtils() {}
+
+    private static String bytesToHexString(byte[] src) {
+        if (src == null || src.length <= 0) {
+            return null;
+        }
+        StringBuilder stringBuilder = new StringBuilder();
+        for (byte b : src) {
+            int v = b & 0xFF;
+            String hv = Integer.toHexString(v).toUpperCase();
+            if (hv.length() < 2) {
+                stringBuilder.append(0);
+            }
+            stringBuilder.append(hv);
+        }
+        return stringBuilder.toString();
+    }
+
+    public static boolean isJarFileType(InputStream input) {
+        if (input == null) {
+            throw new RuntimeException("The inputStream can not be null");
+        }
+        return AutoCloseUtils.using(
+                        input,
+                        in -> {
+                            byte[] b = new byte[4];
+                            try {
+                                in.read(b, 0, b.length);
+                            } catch (IOException e) {
+                                throw new RuntimeException(e);
+                            }
+                            return bytesToHexString(b);
+                        })
+                .equals("504B0304");
+    }
+
+    public static boolean isJarFileType(File file) throws IOException {
+        if (!file.exists() || !file.isFile()) {
+            throw new RuntimeException("The file does not exist or the path is 
a directory");
+        }
+        return isJarFileType(new FileInputStream(file));
+    }
+
+    public static File createTempDir() {
+        final int TEMP_DIR_ATTEMPTS = 10000;
+        File baseDir = new File(System.getProperty("java.io.tmpdir"));
+        String baseName = System.currentTimeMillis() + "-";
+        for (int counter = 0; counter < TEMP_DIR_ATTEMPTS; counter++) {
+            File tempDir = new File(baseDir, baseName + counter);
+            if (tempDir.mkdir()) {
+                return tempDir;
+            }
+        }
+        throw new IllegalStateException(
+                "[StreamPark] Failed to create directory within "
+                        + TEMP_DIR_ATTEMPTS
+                        + "  attempts (tried "
+                        + baseName
+                        + " 0 to "
+                        + baseName
+                        + (TEMP_DIR_ATTEMPTS - 1)
+                        + ")");
+    }
+
+    public static void mkdir(File dir) throws IOException {
+        if (dir.exists() && !dir.isDirectory()) {
+            throw new IOException("File " + dir + " exists and is not a 
directory. Unable to create directory.");
+        } else if (!dir.mkdirs() && !dir.isDirectory()) {
+            throw new IOException("Unable to create directory " + dir);
+        }
+    }
+
+    public static String getPathFromEnv(String env) {
+        String path = System.getenv(env);
+        if (path == null) {
+            path = System.getProperty(env);
+        }
+        AssertUtils.notNull(path, "[StreamPark] FileUtils.getPathFromEnv: " + 
env + " is not set on system env");
+        File file = new File(path);
+        if (!file.exists()) {
+            throw new IllegalArgumentException("[StreamPark] 
FileUtils.getPathFromEnv: " + env + " is not exist!");
+        }
+        return file.getAbsolutePath();
+    }
+
+    public static String resolvePath(String parent, String child) {
+        File file = new File(parent, child);
+        if (!file.exists()) {
+            throw new IllegalArgumentException(
+                    "[StreamPark] FileUtils.resolvePath: " + 
file.getAbsolutePath() + " is not exist!");
+        }
+        return file.getAbsolutePath();
+    }
+
+    public static String getSuffix(String filename) {
+        AssertUtils.notNull(filename);
+        return filename.substring(filename.lastIndexOf("."));
+    }
+
+    public static List<URL> listFileAsURL(String dirPath) {
+        File dir = new File(dirPath);
+        if (dir.exists() && dir.isDirectory()) {
+            File[] files = dir.listFiles();
+            if (files != null && files.length > 0) {
+                List<URL> urls = new ArrayList<>();
+                for (File f : files) {
+                    try {
+                        urls.add(f.toURI().toURL());
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+                return urls;
+            }
+        }
+        return Collections.emptyList();
+    }
+
+    public static boolean exists(Serializable file) {
+        if (file == null) {
+            return false;
+        }
+        if (file instanceof File) {
+            return ((File) file).exists();
+        }
+        return new File(file.toString()).exists();
+    }
+
+    public static boolean directoryNotBlank(Serializable file) {
+        if (file == null) {
+            return false;
+        }
+        File f = file instanceof File ? (File) file : new 
File(file.toString());
+        String[] list = f.list();
+        return f.isDirectory() && list != null && list.length > 0;
+    }
+
+    public static boolean equals(File file1, File file2) throws IOException {
+        if (file1 == null || file2 == null) {
+            return false;
+        }
+        if (!file1.exists() || !file2.exists()) {
+            return false;
+        }
+        if (file1.getAbsolutePath().equals(file2.getAbsolutePath())) {
+            return true;
+        }
+        BufferedInputStream first = new BufferedInputStream(new 
FileInputStream(file1));
+        BufferedInputStream second = new BufferedInputStream(new 
FileInputStream(file2));
+        if (first.available() != second.available()) {
+            Utils.close(first, second);
+            return false;
+        }
+        while (true) {
+            int firRead = first.read();
+            int secRead = second.read();
+            if (firRead != secRead) {
+                Utils.close(first, second);
+                return false;
+            }
+            if (firRead == -1) {
+                Utils.close(first, second);
+                return true;
+            }
+        }
+    }
+
+    public static void readInputStream(InputStream in, byte[] array) throws 
IOException {
+        try (InputStream input = in) {
+            int toRead = array.length;
+            int off = 0;
+            while (toRead > 0) {
+                int ret = input.read(array, off, toRead);
+                if (ret < 0) {
+                    throw new IOException("Bad inputStream, premature EOF");
+                }
+                toRead -= ret;
+                off += ret;
+            }
+        }
+    }
+
+    public static String readFile(File file) throws IOException {
+        if (file.length() >= Integer.MAX_VALUE) {
+            throw new IOException("Too large file, unexpected!");
+        }
+        byte[] array = new byte[(int) file.length()];

Review Comment:
   Fixed in `752fa8a68`: `SafePathUtils` co-locates `Path.resolve()` validation 
with file I/O.



##########
streampark-common/src/main/java/org/apache/streampark/common/util/PropertiesUtils.java:
##########
@@ -0,0 +1,267 @@
+/*
+ * 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.streampark.common.util;
+
+import com.typesafe.config.ConfigFactory;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.streampark.shaded.org.slf4j.Logger;
+import org.yaml.snakeyaml.Yaml;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringReader;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Scanner;
+
+public final class PropertiesUtils {
+
+    private static final Logger LOG =
+            
StreamParkLoggerFactory.loggerFactory().getLogger(PropertiesUtils.class.getName());
+
+    private PropertiesUtils() {}
+
+    public static String readFile(String filename) {
+        File file = new File(filename);
+        if (!file.exists()) {
+            throw new IllegalArgumentException("[StreamPark] readFile: file " 
+ file + " does not exist");
+        }
+        if (!file.isFile()) {
+            throw new IllegalArgumentException("[StreamPark] readFile: file " 
+ file + " is not a normal file");
+        }
+        try (Scanner scanner = new Scanner(file)) {
+            StringBuilder buffer = new StringBuilder();
+            while (scanner.hasNextLine()) {
+                buffer.append(scanner.nextLine()).append("\r\n");
+            }
+            return buffer.toString();
+        } catch (java.io.FileNotFoundException e) {
+            throw new IllegalArgumentException("[StreamPark] readFile: file " 
+ file + " does not exist", e);
+        }
+    }
+
+    public static Map<String, String> fromYamlText(String text) {
+        try {
+            Map<String, Object> map = new Yaml().load(text);
+            return flatten(map);
+        } catch (Exception e) {
+            throw new IllegalArgumentException("Failed when loading conf 
error:", e);
+        }
+    }
+
+    public static Map<String, String> fromHoconText(String conf) {
+        if (conf == null) {
+            throw new IllegalArgumentException("[StreamPark] fromHoconText: 
Hocon content must not be null");
+        }
+        try {
+            return parseHoconByReader(new StringReader(conf));
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Failed when loading Hocon ", 
e);
+        }
+    }
+
+    public static Map<String, String> fromPropertiesText(String conf) {
+        try {
+            Properties properties = new Properties();
+            properties.load(new StringReader(conf));
+            Map<String, String> result = new HashMap<>();
+            for (String k : properties.stringPropertyNames()) {
+                result.put(k, properties.getProperty(k).trim());
+            }
+            return result;
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Failed when loading properties 
", e);
+        }
+    }
+
+    public static Map<String, String> fromYamlFile(String filename) {
+        File file = new File(filename);
+        if (!file.exists()) {

Review Comment:
   Fixed in `752fa8a68`: `SafePathUtils` co-locates `Path.resolve()` validation 
with file I/O.



##########
streampark-common/src/main/java/org/apache/streampark/common/util/PropertiesUtils.java:
##########
@@ -0,0 +1,267 @@
+/*
+ * 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.streampark.common.util;
+
+import com.typesafe.config.ConfigFactory;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.streampark.shaded.org.slf4j.Logger;
+import org.yaml.snakeyaml.Yaml;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringReader;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Scanner;
+
+public final class PropertiesUtils {
+
+    private static final Logger LOG =
+            
StreamParkLoggerFactory.loggerFactory().getLogger(PropertiesUtils.class.getName());
+
+    private PropertiesUtils() {}
+
+    public static String readFile(String filename) {
+        File file = new File(filename);
+        if (!file.exists()) {
+            throw new IllegalArgumentException("[StreamPark] readFile: file " 
+ file + " does not exist");
+        }
+        if (!file.isFile()) {
+            throw new IllegalArgumentException("[StreamPark] readFile: file " 
+ file + " is not a normal file");
+        }
+        try (Scanner scanner = new Scanner(file)) {
+            StringBuilder buffer = new StringBuilder();
+            while (scanner.hasNextLine()) {
+                buffer.append(scanner.nextLine()).append("\r\n");
+            }
+            return buffer.toString();
+        } catch (java.io.FileNotFoundException e) {
+            throw new IllegalArgumentException("[StreamPark] readFile: file " 
+ file + " does not exist", e);
+        }
+    }
+
+    public static Map<String, String> fromYamlText(String text) {
+        try {
+            Map<String, Object> map = new Yaml().load(text);
+            return flatten(map);
+        } catch (Exception e) {
+            throw new IllegalArgumentException("Failed when loading conf 
error:", e);
+        }
+    }
+
+    public static Map<String, String> fromHoconText(String conf) {
+        if (conf == null) {
+            throw new IllegalArgumentException("[StreamPark] fromHoconText: 
Hocon content must not be null");
+        }
+        try {
+            return parseHoconByReader(new StringReader(conf));
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Failed when loading Hocon ", 
e);
+        }
+    }
+
+    public static Map<String, String> fromPropertiesText(String conf) {
+        try {
+            Properties properties = new Properties();
+            properties.load(new StringReader(conf));
+            Map<String, String> result = new HashMap<>();
+            for (String k : properties.stringPropertyNames()) {
+                result.put(k, properties.getProperty(k).trim());
+            }
+            return result;
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Failed when loading properties 
", e);
+        }
+    }
+
+    public static Map<String, String> fromYamlFile(String filename) {
+        File file = new File(filename);
+        if (!file.exists()) {
+            throw new IllegalArgumentException("[StreamPark] fromYamlFile: 
Yaml file " + file + " does not exist");
+        }
+        if (!file.isFile()) {

Review Comment:
   Fixed in `752fa8a68`: `SafePathUtils` co-locates `Path.resolve()` validation 
with file I/O.



##########
streampark-common/src/main/java/org/apache/streampark/common/util/PropertiesUtils.java:
##########
@@ -0,0 +1,267 @@
+/*
+ * 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.streampark.common.util;
+
+import com.typesafe.config.ConfigFactory;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.streampark.shaded.org.slf4j.Logger;
+import org.yaml.snakeyaml.Yaml;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringReader;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Scanner;
+
+public final class PropertiesUtils {
+
+    private static final Logger LOG =
+            
StreamParkLoggerFactory.loggerFactory().getLogger(PropertiesUtils.class.getName());
+
+    private PropertiesUtils() {}
+
+    public static String readFile(String filename) {
+        File file = new File(filename);
+        if (!file.exists()) {
+            throw new IllegalArgumentException("[StreamPark] readFile: file " 
+ file + " does not exist");
+        }
+        if (!file.isFile()) {
+            throw new IllegalArgumentException("[StreamPark] readFile: file " 
+ file + " is not a normal file");
+        }
+        try (Scanner scanner = new Scanner(file)) {
+            StringBuilder buffer = new StringBuilder();
+            while (scanner.hasNextLine()) {
+                buffer.append(scanner.nextLine()).append("\r\n");
+            }
+            return buffer.toString();
+        } catch (java.io.FileNotFoundException e) {
+            throw new IllegalArgumentException("[StreamPark] readFile: file " 
+ file + " does not exist", e);
+        }
+    }
+
+    public static Map<String, String> fromYamlText(String text) {
+        try {
+            Map<String, Object> map = new Yaml().load(text);
+            return flatten(map);
+        } catch (Exception e) {
+            throw new IllegalArgumentException("Failed when loading conf 
error:", e);
+        }
+    }
+
+    public static Map<String, String> fromHoconText(String conf) {
+        if (conf == null) {
+            throw new IllegalArgumentException("[StreamPark] fromHoconText: 
Hocon content must not be null");
+        }
+        try {
+            return parseHoconByReader(new StringReader(conf));
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Failed when loading Hocon ", 
e);
+        }
+    }
+
+    public static Map<String, String> fromPropertiesText(String conf) {
+        try {
+            Properties properties = new Properties();
+            properties.load(new StringReader(conf));
+            Map<String, String> result = new HashMap<>();
+            for (String k : properties.stringPropertyNames()) {
+                result.put(k, properties.getProperty(k).trim());
+            }
+            return result;
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Failed when loading properties 
", e);
+        }
+    }
+
+    public static Map<String, String> fromYamlFile(String filename) {
+        File file = new File(filename);
+        if (!file.exists()) {
+            throw new IllegalArgumentException("[StreamPark] fromYamlFile: 
Yaml file " + file + " does not exist");
+        }
+        if (!file.isFile()) {
+            throw new IllegalArgumentException("[StreamPark] fromYamlFile: 
Yaml file " + file + " is not a normal file");
+        }
+        try (InputStream inputStream = new FileInputStream(file)) {
+            return fromYamlFile(inputStream);
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Failed when loading yaml from 
file", e);
+        }
+    }
+
+    public static Map<String, String> fromHoconFile(String filename) {
+        File file = new File(filename);
+        if (!file.exists()) {

Review Comment:
   Fixed in `752fa8a68`: `SafePathUtils` co-locates `Path.resolve()` validation 
with file I/O.



-- 
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