package com.paymentlink.service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.security.SecureRandom; @Service public class NodeIdService { private static final Logger logger = LoggerFactory.getLogger(NodeIdService.class); private static final SecureRandom RANDOM = new SecureRandom(); private static final String CHARACTERS = "abcdefghijklmnopqrstuvwxyz0123456789"; @Value("${app.server-id-file:incl/server-id.txt}") private String serverIdFile; @Value("${app.tld:ironpath.ai}") private String tld; private String nodeId; /** * Get or create node ID */ public String getNodeId() { if (nodeId == null) { nodeId = loadOrCreateNodeId(); } return nodeId; } /** * Get short ID (without TLD) */ public String getShortId() { String fullId = getNodeId(); return fullId.split("\\.")[0]; } private String loadOrCreateNodeId() { try { Path filePath = Paths.get(serverIdFile); // Ensure parent directory exists if (filePath.getParent() != null) { Files.createDirectories(filePath.getParent()); } // Try to read existing ID if (Files.exists(filePath)) { String id = Files.readString(filePath).trim(); if (!id.isEmpty()) { logger.info("Loaded existing server ID: {}", id); return id; } } // Generate new ID String newId = generateNodeId(); Files.writeString(filePath, newId); logger.info("Generated new server ID: {}", newId); return newId; } catch (IOException e) { logger.error("Failed to load/create server ID file", e); // Generate temporary ID String tempId = generateNodeId(); logger.warn("Using temporary server ID: {}", tempId); return tempId; } } private String generateNodeId() { StringBuilder sb = new StringBuilder(6); for (int i = 0; i < 6; i++) { sb.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); } return sb.toString() + "." + tld; } }