diff --git a/pom.xml b/pom.xml index e274432..ffcddc1 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ 3.7.3 1.18.32 2.17.0 - 8.12.2 + 33.0.0-jre 2.1.3 @@ -133,16 +133,7 @@ ${jakarta.mail.version} - - - io.quarkus - quarkus-elasticsearch-rest-client - - - co.elastic.clients - elasticsearch-java - ${elasticsearch.version} - + diff --git a/src/main/java/dev/lions/config/ElasticsearchConfig.java b/src/main/java/dev/lions/config/ElasticsearchConfig.java deleted file mode 100644 index a40890d..0000000 --- a/src/main/java/dev/lions/config/ElasticsearchConfig.java +++ /dev/null @@ -1,263 +0,0 @@ -package dev.lions.config; - -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.annotation.PostConstruct; -import jakarta.inject.Inject; -import jakarta.validation.constraints.Max; -import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.NotNull; - -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -import org.eclipse.microprofile.config.inject.ConfigProperty; -import dev.lions.exceptions.ConfigurationException; - -import java.time.Duration; -import java.util.Map; -import java.util.HashMap; -import java.util.List; -import java.util.ArrayList; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Configuration Elasticsearch de l'application. - * Cette classe gère l'ensemble des paramètres de configuration pour l'intégration - * Elasticsearch de manière thread-safe et optimisée. - * - * @author Lions Dev Team - * @version 2.0 - */ -@Slf4j -@ApplicationScoped -@Getter -public class ElasticsearchConfig { - - private static final int DEFAULT_SHARDS = 5; - private static final int DEFAULT_REPLICAS = 1; - private static final String INDEX_PREFIX = "lions_"; - private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(30); - private static final int MAX_RETRY_COUNT = 3; - - @Inject - @ConfigProperty(name = "app.environment") - private String environment; - - /** - * Configuration des connexions Elasticsearch. - */ - @Getter - public static class ConnectionConfig { - @NotNull - private String hosts; - - @Min(1) - @Max(65535) - private Integer port = 9200; - - private String username; - private String password; - private Boolean useSsl = false; - - @Min(1000) - private Integer connectionTimeout = 5000; - - @Min(1000) - private Integer socketTimeout = 60000; - - @Min(1000) - private Integer maxRetryTimeout = 60000; - - private Map additionalSettings = new HashMap<>(); - - public void validate() { - if (hosts == null || hosts.trim().isEmpty()) { - throw new ConfigurationException("La configuration des hôtes Elasticsearch est requise"); - } - if (port < 1 || port > 65535) { - throw new ConfigurationException("Port invalide : " + port); - } - if (useSsl && (username == null || password == null)) { - throw new ConfigurationException("Les identifiants sont requis en mode SSL"); - } - } - } - - /** - * Configuration des index Elasticsearch. - */ - @Getter - public static class IndexConfig { - private final Map indices = new ConcurrentHashMap<>(); - private final Map defaultSettings = new HashMap<>(); - private final Map analysisSettings = new HashMap<>(); - - public IndexConfig() { - initializeDefaultSettings(); - initializeAnalysisSettings(); - } - - private void initializeDefaultSettings() { - defaultSettings.put("number_of_shards", DEFAULT_SHARDS); - defaultSettings.put("number_of_replicas", DEFAULT_REPLICAS); - defaultSettings.put("refresh_interval", "1s"); - defaultSettings.put("max_result_window", 10000); - } - - private void initializeAnalysisSettings() { - Map analyzer = new HashMap<>(); - analyzer.put("type", "custom"); - analyzer.put("tokenizer", "standard"); - analyzer.put("filter", List.of("lowercase", "asciifolding")); - - analysisSettings.put("analyzer", Map.of("default_analyzer", analyzer)); - } - - public void addIndex(String name, IndexSettings settings) { - indices.put(name, settings); - } - - public IndexSettings getIndexSettings(String name) { - return indices.getOrDefault(name, createDefaultSettings()); - } - - private IndexSettings createDefaultSettings() { - return new IndexSettings(DEFAULT_SHARDS, DEFAULT_REPLICAS); - } - } - - /** - * Paramètres spécifiques à un index. - */ - @Getter - public static class IndexSettings { - @Min(1) - @Max(50) - private final int numberOfShards; - - @Min(0) - @Max(5) - private final int numberOfReplicas; - - private final Map customSettings; - - public IndexSettings(int numberOfShards, int numberOfReplicas) { - this.numberOfShards = numberOfShards; - this.numberOfReplicas = numberOfReplicas; - this.customSettings = new HashMap<>(); - } - - public void addCustomSetting(String key, Object value) { - customSettings.put(key, value); - } - } - - private final ConnectionConfig connectionConfig = new ConnectionConfig(); - private final IndexConfig indexConfig = new IndexConfig(); - private final Map clientSettings = new HashMap<>(); - - /** - * Initialise la configuration Elasticsearch. - */ - @PostConstruct - public void initialize() { - try { - log.info("Initialisation de la configuration Elasticsearch"); - - validateConfiguration(); - initializeIndices(); - configureClient(); - - log.info("Configuration Elasticsearch initialisée avec succès"); - - } catch (Exception e) { - String message = "Erreur lors de l'initialisation de la configuration Elasticsearch"; - log.error(message, e); - throw new ConfigurationException(message, e); - } - } - - /** - * Valide la configuration Elasticsearch. - */ - private void validateConfiguration() { - log.debug("Validation de la configuration Elasticsearch"); - connectionConfig.validate(); - validateIndices(); - } - - /** - * Valide la configuration des indices. - */ - private void validateIndices() { - indexConfig.getIndices().values().forEach(settings -> { - if (settings.getNumberOfShards() < 1 || settings.getNumberOfShards() > 50) { - throw new ConfigurationException( - "Nombre de shards invalide : " + settings.getNumberOfShards()); - } - if (settings.getNumberOfReplicas() < 0 || settings.getNumberOfReplicas() > 5) { - throw new ConfigurationException( - "Nombre de réplicas invalide : " + settings.getNumberOfReplicas()); - } - }); - } - - /** - * Initialise les indices avec leurs configurations spécifiques. - */ - private void initializeIndices() { - String prefix = getEnvironmentPrefix(); - - IndexSettings projectSettings = new IndexSettings(3, isProduction() ? 2 : 1); - projectSettings.addCustomSetting("refresh_interval", isProduction() ? "30s" : "1s"); - - indexConfig.addIndex(prefix + "projects", projectSettings); - indexConfig.addIndex(prefix + "analytics", new IndexSettings(2, 1)); - } - - /** - * Configure le client Elasticsearch. - */ - private void configureClient() { - clientSettings.put("client.transport.sniff", true); - clientSettings.put("client.transport.ignore_cluster_name", false); - clientSettings.put("client.transport.ping_timeout", "5s"); - clientSettings.put("client.transport.nodes_sampler_interval", "5s"); - - if (isProduction()) { - enhanceProductionSettings(); - } - } - - /** - * Renforce les paramètres de sécurité en production. - */ - private void enhanceProductionSettings() { - clientSettings.put("xpack.security.enabled", true); - clientSettings.put("xpack.security.transport.ssl.enabled", true); - clientSettings.put("xpack.security.transport.ssl.verification_mode", "full"); - } - - /** - * Récupère le préfixe d'environnement pour les noms d'index. - */ - private String getEnvironmentPrefix() { - return isProduction() ? "prod_" : "dev_"; - } - - /** - * Vérifie si l'environnement est en production. - */ - private boolean isProduction() { - return "production".equals(environment); - } - - /** - * Récupère l'URL de connexion complète. - */ - public String getConnectionUrl() { - String protocol = connectionConfig.getUseSsl() ? "https" : "http"; - return String.format("%s://%s:%d", protocol, connectionConfig.getHosts(), - connectionConfig.getPort()); - } -} \ No newline at end of file diff --git a/src/main/java/dev/lions/events/ProjectEventHandler.java b/src/main/java/dev/lions/events/ProjectEventHandler.java index da348c6..753b9eb 100644 --- a/src/main/java/dev/lions/events/ProjectEventHandler.java +++ b/src/main/java/dev/lions/events/ProjectEventHandler.java @@ -5,35 +5,26 @@ import dev.lions.utils.CacheService; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.event.Observes; import jakarta.inject.Inject; -import lombok.extern.slf4j.Slf4j; +import java.util.logging.Logger; -@Slf4j @ApplicationScoped public class ProjectEventHandler { - @Inject - private CacheService cacheService; + private static final Logger log = Logger.getLogger(ProjectEventHandler.class.getName()); @Inject - private SearchIndexService searchIndexService; + private CacheService cacheService; public void onProjectUpdate(@Observes ProjectUpdateEvent event) { try { // Invalidation du cache cacheService.invalidateProjectCache(event.getProjectId()); - // Mise à jour de l'index de recherche - if ("CREATE".equals(event.getAction()) || "UPDATE".equals(event.getAction())) { - searchIndexService.indexProject(event.getProjectId()); - } else if ("DELETE".equals(event.getAction())) { - searchIndexService.removeFromIndex(event.getProjectId()); - } - - log.info("Project event processed successfully. Action: {}, Project ID: {}", - event.getAction(), event.getProjectId()); + log.info("Project event processed successfully. Action: " + event.getAction() + + ", Project ID: " + event.getProjectId()); } catch (Exception e) { - log.error("Error processing project event", e); + log.severe("Error processing project event: " + e.getMessage()); throw new EventProcessingException("Failed to process project event", e); } } diff --git a/src/main/java/dev/lions/events/ProjectUpdateEvent.java b/src/main/java/dev/lions/events/ProjectUpdateEvent.java index 8996e45..3e974aa 100644 --- a/src/main/java/dev/lions/events/ProjectUpdateEvent.java +++ b/src/main/java/dev/lions/events/ProjectUpdateEvent.java @@ -1,26 +1,40 @@ package dev.lions.events; import java.time.LocalDateTime; -import lombok.AllArgsConstructor; -import lombok.Getter; /** * Événement émis lors de la modification ou création d'un projet. Permet de gérer les mises à jour * asynchrones (cache, indexation, etc.). */ -@Getter -@AllArgsConstructor public class ProjectUpdateEvent { private final String projectId; private final String action; // CREATE, UPDATE, DELETE private final LocalDateTime timestamp; + public ProjectUpdateEvent(String projectId, String action, LocalDateTime timestamp) { + this.projectId = projectId; + this.action = action; + this.timestamp = timestamp; + } + public ProjectUpdateEvent(String projectId, String action) { this.projectId = projectId; this.action = action; this.timestamp = LocalDateTime.now(); } + public String getProjectId() { + return projectId; + } + + public String getAction() { + return action; + } + + public LocalDateTime getTimestamp() { + return timestamp; + } + public boolean isCreate() { return "CREATE".equals(action); } diff --git a/src/main/java/dev/lions/events/SearchDocument.java b/src/main/java/dev/lions/events/SearchDocument.java deleted file mode 100644 index 4a99f81..0000000 --- a/src/main/java/dev/lions/events/SearchDocument.java +++ /dev/null @@ -1,25 +0,0 @@ -package dev.lions.events; - -import java.time.LocalDateTime; -import java.util.List; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * Document de recherche pour l'indexation dans Elasticsearch. - * Cette classe représente la structure des documents indexés. - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class SearchDocument { - private String id; - private String title; - private String description; - private List tags; - private List technologies; - private LocalDateTime completionDate; -} \ No newline at end of file diff --git a/src/main/java/dev/lions/events/SearchIndexService.java b/src/main/java/dev/lions/events/SearchIndexService.java deleted file mode 100644 index 8f7de5b..0000000 --- a/src/main/java/dev/lions/events/SearchIndexService.java +++ /dev/null @@ -1,37 +0,0 @@ -package dev.lions.events; - -import dev.lions.models.Project; -import jakarta.enterprise.context.ApplicationScoped; -import lombok.extern.slf4j.Slf4j; - -/** - * Service simplifié pour gérer un index simulé sans Elasticsearch. - */ -@Slf4j -@ApplicationScoped -public class SearchIndexService { - - /** - * Méthode simulée pour indexer un projet. - * - * @param projectId Identifiant unique du projet à indexer - */ - public void indexProject(String projectId) { - log.info("Simulation d'indexation du projet: {}", projectId); - - // Simulation de logique - log.debug("Projet {} ajouté à l'index simulé.", projectId); - } - - /** - * Méthode simulée pour supprimer un projet de l'index. - * - * @param projectId Identifiant unique du projet à supprimer de l'index - */ - public void removeFromIndex(String projectId) { - log.info("Simulation de suppression du projet de l'index: {}", projectId); - - // Simulation de logique - log.debug("Projet {} supprimé de l'index simulé.", projectId); - } -} diff --git a/src/main/java/dev/lions/exceptions/IndexingException.java b/src/main/java/dev/lions/exceptions/IndexingException.java deleted file mode 100644 index d0a9347..0000000 --- a/src/main/java/dev/lions/exceptions/IndexingException.java +++ /dev/null @@ -1,27 +0,0 @@ -package dev.lions.exceptions; - -/** - * Exception personnalisée pour les erreurs d'indexation Elasticsearch. - * Cette exception est levée lorsqu'une opération d'indexation échoue. - */ -public class IndexingException extends RuntimeException { - - /** - * Crée une nouvelle instance avec un message d'erreur. - * - * @param message Le message décrivant l'erreur - */ - public IndexingException(String message) { - super(message); - } - - /** - * Crée une nouvelle instance avec un message et une cause. - * - * @param message Le message décrivant l'erreur - * @param cause La cause originale de l'erreur - */ - public IndexingException(String message, Throwable cause) { - super(message, cause); - } -} \ No newline at end of file