Versions stable (inachevée mais prête à un déploiement en prod)
This commit is contained in:
180
src/main/java/dev/lions/config/ApplicationConfigService.java
Normal file
180
src/main/java/dev/lions/config/ApplicationConfigService.java
Normal file
@@ -0,0 +1,180 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user