Files
lionsdev-client-impl-quarkus/src/main/java/dev/lions/config/ApplicationConfigService.java

181 lines
5.8 KiB
Java

package dev.lions.config;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.Event;
import jakarta.inject.Inject;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import dev.lions.events.ConfigurationEvent;
import dev.lions.exceptions.ConfigurationException;
import dev.lions.utils.EncryptionUtils;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
/**
* Service de gestion avancée de la configuration de l'application.
* Fournit une interface enrichie pour accéder et gérer les paramètres de configuration
* de manière thread-safe, sécurisée et optimisée.
*
* @author Lions Dev Team
* @version 2.1
*/
@Slf4j
@ApplicationScoped
public class ApplicationConfigService {
private static final long CACHE_DURATION_MS = 300_000; // 5 minutes
private static final long MIN_DISK_SPACE_BYTES = 100 * 1024 * 1024; // 100 MB
private static final String[] MANDATORY_DIRECTORIES = {"logs", "data", "temp"};
private final ApplicationConfig applicationConfig;
private final Map<String, CachedValue<Object>> configCache;
private final AtomicLong lastHealthCheck;
@Inject
private Event<ConfigurationEvent> configurationEvent;
@Inject
private EncryptionUtils encryptionUtils;
@Inject
public ApplicationConfigService(@NotNull ApplicationConfig applicationConfig) {
this.applicationConfig = applicationConfig;
this.configCache = new ConcurrentHashMap<>();
this.lastHealthCheck = new AtomicLong(0);
initializeService();
}
/**
* Valide la configuration actuelle de l'application.
* Vérifie les chemins de stockage, les répertoires obligatoires et les paramètres critiques.
*/
private void validateConfiguration() {
log.info("Validation de la configuration de l'application...");
try {
validateStorageBasePath();
validateMandatoryDirectories();
validateSecuritySettings();
log.info("Configuration de l'application validée avec succès.");
} catch (ConfigurationException e) {
log.error("Validation échouée : {}", e.getMessage());
throw e; // Relancer l'exception après log
} catch (Exception e) {
log.error("Erreur inattendue lors de la validation de la configuration", e);
throw new ConfigurationException("Erreur inattendue lors de la validation", e);
}
}
/**
* Vérifie l'existence et l'accessibilité du chemin de stockage.
*/
private void validateStorageBasePath() {
Path storagePath = Paths.get(applicationConfig.getStorageBasePath());
if (!Files.exists(storagePath) || !Files.isDirectory(storagePath)) {
throw new ConfigurationException("Le chemin de stockage est invalide : " + storagePath);
}
log.debug("Chemin de stockage validé : {}", storagePath);
}
/**
* Vérifie l'existence des répertoires obligatoires.
*/
private void validateMandatoryDirectories() {
String basePath = applicationConfig.getStorageBasePath();
for (String directory : MANDATORY_DIRECTORIES) {
Path directoryPath = Paths.get(basePath, directory);
if (!Files.exists(directoryPath) || !Files.isWritable(directoryPath)) {
throw new ConfigurationException("Répertoire obligatoire manquant ou inaccessible : " + directoryPath);
}
log.debug("Répertoire valide : {}", directoryPath);
}
}
/**
* Valide les paramètres de sécurité essentiels.
*/
private void validateSecuritySettings() {
if (applicationConfig.isProduction()) {
if (!applicationConfig.isSmtpConfigured()) {
throw new ConfigurationException("La configuration SMTP est obligatoire en production");
}
log.debug("Paramètres SMTP validés pour l'environnement production");
}
log.debug("Paramètres de sécurité validés");
}
private void initializeService() {
try {
log.info("Initialisation du service de configuration");
createMandatoryDirectories();
validateConfiguration();
initializeCache();
notifyServiceInitialized();
log.info("Service de configuration initialisé avec succès");
} catch (Exception e) {
log.error("Erreur lors de l'initialisation du service de configuration", e);
throw new ConfigurationException("Échec de l'initialisation du service", e);
}
}
private void createMandatoryDirectories() {
String basePath = applicationConfig.getStorageBasePath();
for (String directory : MANDATORY_DIRECTORIES) {
Path directoryPath = Paths.get(basePath, directory);
if (!Files.exists(directoryPath)) {
try {
Files.createDirectories(directoryPath);
log.debug("Répertoire créé : {}", directoryPath);
} catch (Exception e) {
throw new ConfigurationException("Impossible de créer le répertoire : " + directoryPath, e);
}
}
}
}
private void initializeCache() {
log.info("Initialisation du cache de configuration...");
configCache.clear();
}
private void notifyServiceInitialized() {
ConfigurationEvent event = new ConfigurationEvent(
"SERVICE_INITIALIZED",
Map.of("timestamp", System.currentTimeMillis(),
"environment", applicationConfig.getEnvironment())
);
configurationEvent.fire(event);
}
/**
* Classe interne représentant une valeur mise en cache.
*/
private static class CachedValue<T> {
private final T value;
private final long timestamp;
CachedValue(T value) {
this.value = value;
this.timestamp = System.currentTimeMillis();
}
T getValue() {
return value;
}
}
}