This commit is contained in:
2026-04-17 13:57:48 +03:00
parent 031910e848
commit 5759a223d2
11 changed files with 466 additions and 87 deletions

View File

@@ -0,0 +1,105 @@
package su.xserver.iikocon.config;
import io.vertx.core.json.JsonObject;
import java.util.Map;
public class AppConfig {
public ServerConfig server;
public DatabaseConfig database;
public RedisConfig redis;
public static AppConfig from(JsonObject json) {
JsonObject resolved = json.copy();
applyEnvOverrides(resolved);
return resolved.mapTo(AppConfig.class);
}
private static void applyEnvOverrides(JsonObject config) {
Map<String, String> env = System.getenv();
env.forEach((key, value) -> {
String path = envKeyToPath(key);
if (path != null && exists(config, path)) {
setValue(config, path, value);
}
});
}
/**
* SERVER__MAX_POOL_SIZE -> server.maxPoolSize
*/
private static String envKeyToPath(String envKey) {
if (!envKey.contains("__")) {
return null;
}
String[] levels = envKey.toLowerCase().split("__");
for (int i = 0; i < levels.length; i++) {
levels[i] = toCamelCase(levels[i]);
}
return String.join(".", levels);
}
private static String toCamelCase(String value) {
String[] parts = value.split("_");
StringBuilder sb = new StringBuilder(parts[0]);
for (int i = 1; i < parts.length; i++) {
sb.append(Character.toUpperCase(parts[i].charAt(0)))
.append(parts[i].substring(1));
}
return sb.toString();
}
private static boolean exists(JsonObject json, String path) {
String[] parts = path.split("\\.");
JsonObject current = json;
for (int i = 0; i < parts.length - 1; i++) {
if (!current.containsKey(parts[i])) {
return false;
}
current = current.getJsonObject(parts[i]);
}
return current.containsKey(parts[parts.length - 1]);
}
private static void setValue(JsonObject json, String path, String value) {
String[] parts = path.split("\\.");
JsonObject current = json;
for (int i = 0; i < parts.length - 1; i++) {
current = current.getJsonObject(parts[i]);
}
String key = parts[parts.length - 1];
Object oldValue = current.getValue(key);
current.put(key, cast(value, oldValue));
}
private static Object cast(String value, Object oldValue) {
if (oldValue instanceof Integer) return Integer.parseInt(value);
if (oldValue instanceof Long) return Long.parseLong(value);
if (oldValue instanceof Boolean) return Boolean.parseBoolean(value);
if (oldValue == null) return value;
return value;
}
public JsonObject json() {
return new JsonObject()
.put("server", server.json().getJsonObject("server"))
.put("database", database.json().getJsonObject("database"))
.put("redis", redis.json().getJsonObject("redis"));
}
@Override
public String toString() {
return json().encode();
}
}

View File

@@ -0,0 +1,26 @@
package su.xserver.iikocon.config;
import io.vertx.core.json.JsonObject;
public class DatabaseConfig {
public String host;
public int port;
public String database;
public String user;
public String password;
public int connectionTimeout;
public int maxPoolSize;
public JsonObject json() {
return new JsonObject()
.put("database", new JsonObject()
.put("host", host)
.put("port", port)
.put("user", user)
.put("password", password)
.put("database", database)
.put("connectionTimeout", connectionTimeout)
.put("maxPoolSize", maxPoolSize)
);
}
}

View File

@@ -0,0 +1,22 @@
package su.xserver.iikocon.config;
import io.vertx.core.json.JsonObject;
public class RedisConfig {
public String host;
public int port;
public String password;
public int maxPoolSize;
public int maxWaitingHandlers;
public JsonObject json() {
return new JsonObject()
.put("redis", new JsonObject()
.put("host", host)
.put("port", port)
.put("password", password)
.put("maxPoolSize", maxPoolSize)
.put("maxWaitingHandlers", maxWaitingHandlers)
);
}
}

View File

@@ -0,0 +1,16 @@
package su.xserver.iikocon.config;
import io.vertx.core.json.JsonObject;
public class ServerConfig {
public int port;
public String host;
public JsonObject json() {
return new JsonObject()
.put("server", new JsonObject()
.put("port", port)
.put("host", host)
);
}
}