Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public static Properties getProperties(String fileName) throws Exception {
// Load the properties file from the classpath
props.load(input);
} catch (IOException ex) {
ex.printStackTrace();
throw new Exception("Error loading properties file: " + fileName, ex);
}

return props;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,77 +14,66 @@ public class AppConfiguration {
* The host or IP address of the source database server.
*/
@Getter
@Setter
private final String sourceHost;

/**
* The port number of the source database server.
*/
@Getter
@Setter
private final String sourcePort;

/**
* The username used to connect to the source database.
*/
@Getter
@Setter
private final String sourceUserName;

/**
* The password used to connect to the source database.
*/
@Getter
@Setter
private final String sourcePassword;

/**
* The name of the source database.
*/
@Getter
@Setter
private final String sourceDatabase;

/**
* A comma-separated list of source tables to monitor or process.
*/
@Getter
@Setter
private final String sourceTables;

/**
* The host or IP address of the ClickHouse server.
*/
@Getter
@Setter
private final String clickHouseHost;

/**
* The port number of the ClickHouse server.
*/
@Getter
@Setter
private final String clickHousePort;

/**
* The password used to connect to the ClickHouse server.
*/
@Getter
@Setter
private final String clickHousePassword;

/**
* The name of the ClickHouse database.
*/
@Getter
@Setter
private final String clickHouseDatabase;

/**
* The username used to connect to the ClickHouse server.
*/
@Getter
@Setter
private final String clickHouseUserName;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.yaml.snakeyaml.constructor.SafeConstructor;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
Expand All @@ -17,28 +18,16 @@
*/
public class ConfigLoader {

private static Yaml createSafeYaml() {
/**
* Creates a Yaml instance with SafeConstructor to prevent
* arbitrary object deserialization (CVE-2022-1471).
*
* @return A safely-configured Yaml instance.
*/
private Yaml createSafeYaml() {
return new Yaml(new SafeConstructor(new LoaderOptions()));
}

private static Properties toProperties(Map<String, Object> yamlFile) {
final Properties props = new Properties();
if (yamlFile == null) {
return props;
}
for (Map.Entry<String, Object> entry : yamlFile.entrySet()) {
Object value = entry.getValue();
if (value != null) {
String strValue = String.valueOf(value);
if (value instanceof String) {
strValue = strValue.replace("\"", "");
}
props.setProperty(entry.getKey(), strValue);
}
}
return props;
}

/**
* Loads properties from a YAML file located on the classpath.
*
Expand All @@ -47,12 +36,19 @@ private static Properties toProperties(Map<String, Object> yamlFile) {
* key-value pairs.
*/
public Properties load(String resourceFileName) {
InputStream fis = this.getClass()
// Use try-with-resources to ensure the InputStream is closed. 2.10.0's
// variant declared the stream in the resource list but then parsed
// INSIDE the resource specification, which does not compile.
try (InputStream fis = this.getClass()
.getClassLoader()
.getResourceAsStream(resourceFileName);
.getResourceAsStream(resourceFileName)) {

Map<String, Object> yamlFile = createSafeYaml().load(fis);
return toProperties(yamlFile);
Map<String, Object> yamlFile = createSafeYaml().load(fis);

return convertYamlMapToProperties(yamlFile);
} catch (IOException e) {
throw new RuntimeException("Failed to load resource: " + resourceFileName, e);
}
}

/**
Expand All @@ -61,14 +57,53 @@ public Properties load(String resourceFileName) {
* @param fileName The full path of the YAML file.
* @return A {@link Properties} object containing the configuration
* key-value pairs.
* @throws IOException If the specified file cannot be read.
* @throws FileNotFoundException If the specified file does not exist.
*/
public Properties loadFromFile(String fileName)
throws IOException {

throws FileNotFoundException {
// Use try-with-resources to ensure InputStream is closed
try (InputStream fis = new FileInputStream(fileName)) {

Map<String, Object> yamlFile = createSafeYaml().load(fis);
return toProperties(yamlFile);

return convertYamlMapToProperties(yamlFile);
} catch (FileNotFoundException e) {
throw e;
} catch (IOException e) {
throw new RuntimeException("Failed to load file: " + fileName, e);
}
}

/**
* Converts a YAML map to a Properties object, handling all value types
* safely (not just String and Integer).
*
* @param yamlFile The map parsed from the YAML file. May be {@code null}
* when the document is empty.
* @return A {@link Properties} object with string representations of all values.
*/
private Properties convertYamlMapToProperties(Map<String, Object> yamlFile) {
final Properties props = new Properties();

// An empty YAML document parses to null. This guard is carried over
// from the 2.10.0 side of the merge; without it an empty config file
// throws a NullPointerException instead of yielding empty Properties.
if (yamlFile == null) {
return props;
}

for (Map.Entry<String, Object> entry : yamlFile.entrySet()) {
Object value = entry.getValue();
if (value == null) {
continue;
}
// Use toString() instead of casting to (String) to handle
// all YAML value types: Integer, Long, Boolean, Double, etc.
String stringValue = value.toString();
// Strip surrounding quotes if present (legacy behavior)
stringValue = stringValue.replace("\"", "");
props.setProperty(entry.getKey(), stringValue);
}
return props;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,13 @@ public enum EnvironmentVariables {
EnvironmentVariables(String s) {
this.label = s;
}

/**
* Returns the label (property key) for this environment variable.
*
* @return the label string
*/
public String getLabel() {
return label;
}
}
Loading
Loading