SHA256
99 lines
5.5 KiB
Java
99 lines
5.5 KiB
Java
package server.archive;
|
|
|
|
import utils.config.AppConfig;
|
|
import utils.config.SolanaProgramsConfig;
|
|
|
|
import java.nio.file.Path;
|
|
import java.time.LocalTime;
|
|
import java.time.ZoneId;
|
|
|
|
/** Настройки опционального архивного publisher-а. По умолчанию функция выключена. */
|
|
public record ArchivePublisherConfig(
|
|
boolean enabled,
|
|
LocalTime publishTime,
|
|
ZoneId publishZone,
|
|
long maxFileBytes,
|
|
Path workDir,
|
|
String serverLogin,
|
|
String arweaveGateway,
|
|
Path arweaveWalletJwkPath,
|
|
int arweaveMinConfirmations,
|
|
int arweaveConfirmPollSeconds,
|
|
int arweaveConfirmTimeoutMinutes,
|
|
Path solanaRootKeyPath,
|
|
Path solanaClientKeyPath,
|
|
String solanaRpcUrl,
|
|
String solanaUsersProgramId,
|
|
String solanaPaymentsProgramId,
|
|
int solanaConfirmPollSeconds,
|
|
int solanaConfirmTimeoutMinutes,
|
|
String solanaCommitment
|
|
) {
|
|
public static ArchivePublisherConfig load() {
|
|
AppConfig c = AppConfig.getInstance();
|
|
return new ArchivePublisherConfig(
|
|
c.getBoolean("archive.publish.enabled", false),
|
|
parseTime(orDefault(c.getParam("archive.publish.time"), "00:00")),
|
|
parseZone(c.getParam("archive.publish.zoneId")),
|
|
positiveLong(parseLong(c.getParam("archive.maxFileBytes"), 4_000_000_000L), "archive.maxFileBytes"),
|
|
Path.of(orDefault(c.getParam("archive.workDir"), "data/archive")),
|
|
requiredIfEnabled(c, "server.SHiNE.login"),
|
|
orDefault(c.getParam("archive.arweave.gateway"), "https://arweave.net"),
|
|
optionalPath(c.getParam("archive.arweave.walletJwkPath")),
|
|
nonNegative(c.getInt("archive.arweave.minConfirmations", 1), "archive.arweave.minConfirmations"),
|
|
positive(c.getInt("archive.arweave.confirmPollSeconds", 30), "archive.arweave.confirmPollSeconds"),
|
|
positive(c.getInt("archive.arweave.confirmTimeoutMinutes", 180), "archive.arweave.confirmTimeoutMinutes"),
|
|
optionalPath(c.getParam("archive.solana.rootKeyPath")),
|
|
optionalPath(c.getParam("archive.solana.clientKeyPath")),
|
|
firstNonBlank(c.getParam("solana.users.sync.rpcUrl"), c.getParam("solana.rpcUrl"), SolanaProgramsConfig.SOLANA_RPC_URL),
|
|
firstNonBlank(c.getParam("solana.users.sync.programId"), SolanaProgramsConfig.SHINE_USERS_PROGRAM_ID),
|
|
SolanaProgramsConfig.SHINE_PAYMENTS_PROGRAM_ID,
|
|
positive(c.getInt("archive.solana.confirmPollSeconds", 5), "archive.solana.confirmPollSeconds"),
|
|
positive(c.getInt("archive.solana.confirmTimeoutMinutes", 30), "archive.solana.confirmTimeoutMinutes"),
|
|
orDefault(c.getParam("archive.solana.commitment"), "finalized")
|
|
);
|
|
}
|
|
|
|
public void validateForStart() {
|
|
if (!enabled) return;
|
|
if (serverLogin == null || serverLogin.isBlank()) throw new IllegalArgumentException("server.SHiNE.login обязателен для archive publisher");
|
|
if (arweaveWalletJwkPath == null) throw new IllegalArgumentException("archive.arweave.walletJwkPath обязателен");
|
|
if (solanaRootKeyPath == null) throw new IllegalArgumentException("archive.solana.rootKeyPath обязателен");
|
|
if (solanaClientKeyPath == null) throw new IllegalArgumentException("archive.solana.clientKeyPath обязателен");
|
|
if (solanaRpcUrl == null || solanaRpcUrl.isBlank()) throw new IllegalArgumentException("solana.users.sync.rpcUrl или solana.rpcUrl обязателен");
|
|
if (maxFileBytes >= 0x1_0000_0000L) {
|
|
throw new IllegalArgumentException("SHINE-ARCHIVE v1 требует archive.maxFileBytes < 4294967296");
|
|
}
|
|
}
|
|
|
|
private static String requiredIfEnabled(AppConfig c, String name) {
|
|
String v = c.getParam(name);
|
|
return v == null ? "" : v.trim();
|
|
}
|
|
private static Path optionalPath(String s) { return s == null || s.isBlank() ? null : Path.of(s.trim()); }
|
|
private static String firstNonBlank(String... values) {
|
|
if (values != null) for (String v : values) if (v != null && !v.isBlank()) return v.trim();
|
|
return "";
|
|
}
|
|
private static String orDefault(String v, String d) { return v == null || v.isBlank() ? d : v.trim(); }
|
|
private static long parseLong(String s, long d) { return s == null || s.isBlank() ? d : Long.parseLong(s.trim()); }
|
|
private static LocalTime parseTime(String value) {
|
|
try {
|
|
return LocalTime.parse(value.trim());
|
|
} catch (Exception e) {
|
|
throw new IllegalArgumentException("archive.publish.time должен быть в формате HH:mm, например 00:00", e);
|
|
}
|
|
}
|
|
private static ZoneId parseZone(String value) {
|
|
if (value == null || value.isBlank()) return ZoneId.systemDefault();
|
|
try {
|
|
return ZoneId.of(value.trim());
|
|
} catch (Exception e) {
|
|
throw new IllegalArgumentException("Некорректный archive.publish.zoneId: " + value, e);
|
|
}
|
|
}
|
|
private static int positive(int v, String n) { if (v <= 0) throw new IllegalArgumentException(n + " должен быть > 0"); return v; }
|
|
private static int nonNegative(int v, String n) { if (v < 0) throw new IllegalArgumentException(n + " должен быть >= 0"); return v; }
|
|
private static long positiveLong(long v, String n) { if (v <= 0) throw new IllegalArgumentException(n + " должен быть > 0"); return v; }
|
|
}
|