From 88711e53859b6124a60a6909d91526ee31648a64 Mon Sep 17 00:00:00 2001 From: BOUHOURS Antoine Date: Fri, 3 Apr 2026 12:17:19 +0200 Subject: [PATCH 1/7] Test design not saving process type in config --- ....java => AbstractProcessConfigEntity.java} | 12 ++------- .../SecurityAnalysisConfigEntity.java | 10 ++++--- .../SecurityAnalysisConfigMapper.java | 3 ++- .../repositories/ProcessConfigRepository.java | 7 ++--- ...curityAnalysisProcessConfigRepository.java | 20 ++++++++++++++ .../processconfig/ProcessConfigService.java | 27 ++++++++++++------- .../changesets/changelog_20260403T101411Z.xml | 6 +++++ .../db/changelog/db.changelog-master.yaml | 3 +++ .../ProcessConfigServiceTest.java | 12 ++++++--- 9 files changed, 68 insertions(+), 32 deletions(-) rename monitor-server/src/main/java/org/gridsuite/monitor/server/entities/processconfig/{ProcessConfigEntity.java => AbstractProcessConfigEntity.java} (80%) create mode 100644 monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/SecurityAnalysisProcessConfigRepository.java create mode 100644 monitor-server/src/main/resources/db/changelog/changesets/changelog_20260403T101411Z.xml diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/entities/processconfig/ProcessConfigEntity.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/entities/processconfig/AbstractProcessConfigEntity.java similarity index 80% rename from monitor-server/src/main/java/org/gridsuite/monitor/server/entities/processconfig/ProcessConfigEntity.java rename to monitor-server/src/main/java/org/gridsuite/monitor/server/entities/processconfig/AbstractProcessConfigEntity.java index e3c303cb..c5f4a15e 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/entities/processconfig/ProcessConfigEntity.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/entities/processconfig/AbstractProcessConfigEntity.java @@ -8,11 +8,8 @@ import jakarta.persistence.CollectionTable; import jakarta.persistence.Column; -import jakarta.persistence.DiscriminatorColumn; import jakarta.persistence.ElementCollection; import jakarta.persistence.Entity; -import jakarta.persistence.EnumType; -import jakarta.persistence.Enumerated; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; @@ -32,20 +29,17 @@ import java.util.List; import java.util.UUID; -import static jakarta.persistence.DiscriminatorType.STRING; - /** * @author Franck Lecuyer */ @Entity @Table(name = "process_config") @Inheritance(strategy = InheritanceType.JOINED) -@DiscriminatorColumn(name = "process_type", discriminatorType = STRING) @NoArgsConstructor @AllArgsConstructor @Getter @Setter -public class ProcessConfigEntity { +public abstract class AbstractProcessConfigEntity { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id") @@ -59,9 +53,7 @@ public class ProcessConfigEntity { @OrderColumn(name = "pos_modifications") private List modificationUuids; - @Enumerated(EnumType.STRING) - @Column(name = "process_type", insertable = false, updatable = false) - private ProcessType processType; + public abstract ProcessType getProcessType(); } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/entities/processconfig/SecurityAnalysisConfigEntity.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/entities/processconfig/SecurityAnalysisConfigEntity.java index dc1776bc..c19af2a7 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/entities/processconfig/SecurityAnalysisConfigEntity.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/entities/processconfig/SecurityAnalysisConfigEntity.java @@ -7,7 +7,6 @@ package org.gridsuite.monitor.server.entities.processconfig; import jakarta.persistence.Column; -import jakarta.persistence.DiscriminatorValue; import jakarta.persistence.Entity; import jakarta.persistence.ForeignKey; import jakarta.persistence.PrimaryKeyJoinColumn; @@ -16,6 +15,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import java.util.UUID; @@ -24,16 +24,20 @@ */ @Entity @Table(name = "security_analysis_config") -@DiscriminatorValue("SECURITY_ANALYSIS") @PrimaryKeyJoinColumn(foreignKey = @ForeignKey(name = "securityAnalysisConfig_id_fk_constraint")) @NoArgsConstructor @AllArgsConstructor @Getter @Setter -public class SecurityAnalysisConfigEntity extends ProcessConfigEntity { +public class SecurityAnalysisConfigEntity extends AbstractProcessConfigEntity { @Column(name = "security_analysis_parameters_uuid") private UUID securityAnalysisParametersUuid; @Column(name = "loadflow_parameters_uuid") private UUID loadflowParametersUuid; + + @Override + public ProcessType getProcessType() { + return ProcessType.SECURITY_ANALYSIS; + } } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/mappers/processconfig/SecurityAnalysisConfigMapper.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/mappers/processconfig/SecurityAnalysisConfigMapper.java index ba9089e4..c0b9fef4 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/mappers/processconfig/SecurityAnalysisConfigMapper.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/mappers/processconfig/SecurityAnalysisConfigMapper.java @@ -17,10 +17,11 @@ */ @Mapper(componentModel = "spring") public interface SecurityAnalysisConfigMapper { - @Mapping(target = "processType", expression = "java(dto.processType())") + @Mapping(target = "id", ignore = true) SecurityAnalysisConfigEntity toEntity(SecurityAnalysisConfig dto); SecurityAnalysisConfig toDto(SecurityAnalysisConfigEntity dto); + @Mapping(target = "id", ignore = true) void updateEntityFromDto(SecurityAnalysisConfig dto, @MappingTarget SecurityAnalysisConfigEntity entity); } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/ProcessConfigRepository.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/ProcessConfigRepository.java index bafc6d23..fa0e816f 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/ProcessConfigRepository.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/ProcessConfigRepository.java @@ -6,18 +6,15 @@ */ package org.gridsuite.monitor.server.repositories; -import org.gridsuite.monitor.commons.types.processexecution.ProcessType; -import org.gridsuite.monitor.server.entities.processconfig.ProcessConfigEntity; +import org.gridsuite.monitor.server.entities.processconfig.AbstractProcessConfigEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import java.util.List; import java.util.UUID; /** * @author Franck Lecuyer */ @Repository -public interface ProcessConfigRepository extends JpaRepository { - List findAllByProcessType(ProcessType processType); +public interface ProcessConfigRepository extends JpaRepository { } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/SecurityAnalysisProcessConfigRepository.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/SecurityAnalysisProcessConfigRepository.java new file mode 100644 index 00000000..695bb082 --- /dev/null +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/SecurityAnalysisProcessConfigRepository.java @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.monitor.server.repositories; + +import org.gridsuite.monitor.server.entities.processconfig.SecurityAnalysisConfigEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.UUID; + +/** + * @author Franck Lecuyer + */ +@Repository +public interface SecurityAnalysisProcessConfigRepository extends JpaRepository { +} diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java index 1f43a16b..df575cac 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java @@ -13,10 +13,11 @@ import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigComparison; import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; import org.gridsuite.monitor.server.dto.processconfig.PersistedProcessConfig; -import org.gridsuite.monitor.server.entities.processconfig.ProcessConfigEntity; +import org.gridsuite.monitor.server.entities.processconfig.AbstractProcessConfigEntity; import org.gridsuite.monitor.server.entities.processconfig.SecurityAnalysisConfigEntity; import org.gridsuite.monitor.server.mappers.processconfig.SecurityAnalysisConfigMapper; import org.gridsuite.monitor.server.repositories.ProcessConfigRepository; +import org.gridsuite.monitor.server.repositories.SecurityAnalysisProcessConfigRepository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -28,10 +29,12 @@ @Service public class ProcessConfigService { private final ProcessConfigRepository processConfigRepository; + private final SecurityAnalysisProcessConfigRepository securityAnalysisProcessConfigRepository; private final SecurityAnalysisConfigMapper securityAnalysisConfigMapper; - public ProcessConfigService(ProcessConfigRepository processConfigRepository, SecurityAnalysisConfigMapper securityAnalysisConfigMapper) { + public ProcessConfigService(ProcessConfigRepository processConfigRepository, SecurityAnalysisProcessConfigRepository securityAnalysisProcessConfigRepository, SecurityAnalysisConfigMapper securityAnalysisConfigMapper) { this.processConfigRepository = processConfigRepository; + this.securityAnalysisProcessConfigRepository = securityAnalysisProcessConfigRepository; this.securityAnalysisConfigMapper = securityAnalysisConfigMapper; } @@ -95,26 +98,32 @@ public boolean deleteProcessConfig(UUID processConfigUuid) { @Transactional(readOnly = true) public List getProcessConfigs(ProcessType processType) { - return processConfigRepository.findAllByProcessType(processType).stream() - .map(this::toPersistedProcessConfig) - .toList(); + switch (processType) { + case SECURITY_ANALYSIS -> { + return securityAnalysisProcessConfigRepository.findAll() + .stream() + .map(this::toPersistedProcessConfig) + .toList(); + } + default -> throw new IllegalArgumentException("Unsupported process type: " + processType); + } } - private ProcessConfig toProcessConfig(ProcessConfigEntity entity) { + private ProcessConfig toProcessConfig(AbstractProcessConfigEntity entity) { return switch (entity) { case SecurityAnalysisConfigEntity sae -> securityAnalysisConfigMapper.toDto(sae); default -> throw new IllegalArgumentException("Unsupported entity type: " + entity.getProcessType()); }; } - private PersistedProcessConfig toPersistedProcessConfig(ProcessConfigEntity entity) { + private PersistedProcessConfig toPersistedProcessConfig(AbstractProcessConfigEntity entity) { return new PersistedProcessConfig(entity.getId(), toProcessConfig(entity)); } @Transactional(readOnly = true) public Optional compareProcessConfigs(UUID uuid1, UUID uuid2) { - Optional processConfigEntity1 = processConfigRepository.findById(uuid1); - Optional processConfigEntity2 = processConfigRepository.findById(uuid2); + Optional processConfigEntity1 = processConfigRepository.findById(uuid1); + Optional processConfigEntity2 = processConfigRepository.findById(uuid2); if (processConfigEntity1.isEmpty() || processConfigEntity2.isEmpty()) { return Optional.empty(); diff --git a/monitor-server/src/main/resources/db/changelog/changesets/changelog_20260403T101411Z.xml b/monitor-server/src/main/resources/db/changelog/changesets/changelog_20260403T101411Z.xml new file mode 100644 index 00000000..df4e2672 --- /dev/null +++ b/monitor-server/src/main/resources/db/changelog/changesets/changelog_20260403T101411Z.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/monitor-server/src/main/resources/db/changelog/db.changelog-master.yaml b/monitor-server/src/main/resources/db/changelog/db.changelog-master.yaml index 38ad3a30..37f7c7d5 100644 --- a/monitor-server/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/monitor-server/src/main/resources/db/changelog/db.changelog-master.yaml @@ -14,3 +14,6 @@ databaseChangeLog: - include: file: changesets/changelog_20260227T101113Z.xml relativeToChangelogFile: true + - include: + file: changesets/changelog_20260403T101411Z.xml + relativeToChangelogFile: true diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java index cf6ac9db..235b469b 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java @@ -15,6 +15,7 @@ import org.gridsuite.monitor.server.entities.processconfig.SecurityAnalysisConfigEntity; import org.gridsuite.monitor.server.mappers.processconfig.SecurityAnalysisConfigMapper; import org.gridsuite.monitor.server.repositories.ProcessConfigRepository; +import org.gridsuite.monitor.server.repositories.SecurityAnalysisProcessConfigRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -41,6 +42,9 @@ class ProcessConfigServiceTest { @Mock private ProcessConfigRepository processConfigRepository; + @Mock + private SecurityAnalysisProcessConfigRepository securityAnalysisProcessConfigRepository; + @InjectMocks private ProcessConfigService processConfigService; @@ -236,12 +240,12 @@ void getSecurityAnalysisConfigs() { SecurityAnalysisConfig securityAnalysisConfig2 = new SecurityAnalysisConfig(UUID.randomUUID(), List.of(UUID.randomUUID()), UUID.randomUUID()); SecurityAnalysisConfigEntity securityAnalysisConfigEntity2 = securityAnalysisConfigMapper.toEntity(securityAnalysisConfig2); - when(processConfigRepository.findAllByProcessType(ProcessType.SECURITY_ANALYSIS)) + when(securityAnalysisProcessConfigRepository.findAll()) .thenReturn(List.of(securityAnalysisConfigEntity1, securityAnalysisConfigEntity2)); List processConfigs = processConfigService.getProcessConfigs(ProcessType.SECURITY_ANALYSIS); - verify(processConfigRepository).findAllByProcessType(ProcessType.SECURITY_ANALYSIS); + verify(securityAnalysisProcessConfigRepository).findAll(); assertThat(processConfigs).hasSize(2); assertThat(processConfigs.get(0).processConfig().processType()).isEqualTo(ProcessType.SECURITY_ANALYSIS); assertThat(processConfigs.get(1).processConfig().processType()).isEqualTo(ProcessType.SECURITY_ANALYSIS); @@ -257,11 +261,11 @@ void getSecurityAnalysisConfigs() { @Test void getSecurityAnalysisConfigsNotFound() { - when(processConfigRepository.findAllByProcessType(ProcessType.SECURITY_ANALYSIS)).thenReturn(List.of()); + when(securityAnalysisProcessConfigRepository.findAll()).thenReturn(List.of()); List processConfigs = processConfigService.getProcessConfigs(ProcessType.SECURITY_ANALYSIS); - verify(processConfigRepository).findAllByProcessType(ProcessType.SECURITY_ANALYSIS); + verify(securityAnalysisProcessConfigRepository).findAll(); assertThat(processConfigs).isEmpty(); } From 0a5286590ca6203a6b2e7ade6f4420b361392aae Mon Sep 17 00:00:00 2001 From: BOUHOURS Antoine Date: Fri, 3 Apr 2026 12:31:09 +0200 Subject: [PATCH 2/7] Startegy pattern --- .../processconfig/ProcessConfigHandler.java | 51 ++++++++ .../processconfig/ProcessConfigService.java | 109 +++++------------- .../SecurityAnalysisConfigHandler.java | 77 +++++++++++++ .../ProcessConfigServiceTest.java | 12 +- 4 files changed, 167 insertions(+), 82 deletions(-) create mode 100644 monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java create mode 100644 monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java new file mode 100644 index 00000000..473f81f1 --- /dev/null +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.monitor.server.services.processconfig; + +import org.gridsuite.monitor.commons.types.processconfig.ProcessConfig; +import org.gridsuite.monitor.commons.types.processexecution.ProcessType; +import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; +import org.gridsuite.monitor.server.entities.processconfig.AbstractProcessConfigEntity; + +import java.util.List; + +/** + * Handler for a specific {@link ProcessConfig} type. Encapsulates all type-specific + * logic (mapping, persistence, comparison) so that {@link ProcessConfigService} remains + * free of per-type switch statements. Add a new Spring {@code @Component} implementation + * of this interface for every new config type. + * + * @param the DTO type (must implement {@link ProcessConfig}) + * @param the JPA entity type (must extend {@link AbstractProcessConfigEntity}) + */ +public interface ProcessConfigHandler { + + /** Returns the {@link ProcessType} this handler is responsible for. */ + ProcessType getProcessType(); + + /** Converts a DTO to a new (unsaved) entity. The entity {@code id} must be left null. */ + E toEntity(C config); + + /** Converts an entity to its DTO representation. */ + C toDto(E entity); + + /** + * Applies the fields of {@code config} onto {@code entity} in place. + * The entity {@code id} must not be modified. + */ + void updateEntity(C config, E entity); + + /** Returns all persisted entities of this type. */ + List findAll(); + + /** + * Compares two DTOs of this type field by field. + * + * @return a list of {@link ProcessConfigFieldComparison} entries, one per compared field + */ + List compare(C config1, C config2); +} diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java index df575cac..8f76dace 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java @@ -7,21 +7,21 @@ package org.gridsuite.monitor.server.services.processconfig; import org.gridsuite.monitor.commons.types.processconfig.ProcessConfig; -import org.gridsuite.monitor.commons.types.processconfig.SecurityAnalysisConfig; import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import org.gridsuite.monitor.server.dto.processconfig.MetadataInfos; import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigComparison; import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; import org.gridsuite.monitor.server.dto.processconfig.PersistedProcessConfig; import org.gridsuite.monitor.server.entities.processconfig.AbstractProcessConfigEntity; -import org.gridsuite.monitor.server.entities.processconfig.SecurityAnalysisConfigEntity; -import org.gridsuite.monitor.server.mappers.processconfig.SecurityAnalysisConfigMapper; import org.gridsuite.monitor.server.repositories.ProcessConfigRepository; -import org.gridsuite.monitor.server.repositories.SecurityAnalysisProcessConfigRepository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.*; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; /** * @author Franck Lecuyer @@ -29,27 +29,29 @@ @Service public class ProcessConfigService { private final ProcessConfigRepository processConfigRepository; - private final SecurityAnalysisProcessConfigRepository securityAnalysisProcessConfigRepository; - private final SecurityAnalysisConfigMapper securityAnalysisConfigMapper; + private final Map> handlers; - public ProcessConfigService(ProcessConfigRepository processConfigRepository, SecurityAnalysisProcessConfigRepository securityAnalysisProcessConfigRepository, SecurityAnalysisConfigMapper securityAnalysisConfigMapper) { + @SuppressWarnings("unchecked") + public ProcessConfigService(ProcessConfigRepository processConfigRepository, + List> handlers) { this.processConfigRepository = processConfigRepository; - this.securityAnalysisProcessConfigRepository = securityAnalysisProcessConfigRepository; - this.securityAnalysisConfigMapper = securityAnalysisConfigMapper; + this.handlers = handlers.stream().collect(Collectors.toMap( + ProcessConfigHandler::getProcessType, + h -> (ProcessConfigHandler) h + )); } - @Transactional - public UUID createProcessConfig(ProcessConfig processConfig) { - return doCreateProcessConfig(processConfig); + private ProcessConfigHandler getHandler(ProcessType processType) { + ProcessConfigHandler handler = handlers.get(processType); + if (handler == null) { + throw new IllegalArgumentException("Unsupported process config type: " + processType); + } + return handler; } - private UUID doCreateProcessConfig(ProcessConfig processConfig) { - switch (processConfig) { - case SecurityAnalysisConfig sac -> { - return processConfigRepository.save(securityAnalysisConfigMapper.toEntity(sac)).getId(); - } - default -> throw new IllegalArgumentException("Unsupported process config type: " + processConfig.processType()); - } + @Transactional + public UUID createProcessConfig(ProcessConfig processConfig) { + return processConfigRepository.save(getHandler(processConfig.processType()).toEntity(processConfig)).getId(); } @Transactional(readOnly = true) @@ -71,11 +73,7 @@ public boolean updateProcessConfig(UUID processConfigUuid, ProcessConfig process if (entity.getProcessType() != processConfig.processType()) { throw new IllegalArgumentException("Process config type mismatch : " + entity.getProcessType()); } - switch (processConfig) { - case SecurityAnalysisConfig sac -> - securityAnalysisConfigMapper.updateEntityFromDto(sac, (SecurityAnalysisConfigEntity) entity); - default -> throw new IllegalArgumentException("Unsupported process config type: " + processConfig.processType()); - } + getHandler(processConfig.processType()).updateEntity(processConfig, entity); return true; }) .orElse(false); @@ -84,7 +82,10 @@ public boolean updateProcessConfig(UUID processConfigUuid, ProcessConfig process @Transactional public Optional duplicateProcessConfig(UUID sourceProcessConfigUuid) { return processConfigRepository.findById(sourceProcessConfigUuid) - .map(sourceEntity -> doCreateProcessConfig(toProcessConfig(sourceEntity))); + .map(sourceEntity -> { + ProcessConfig sourceConfig = toProcessConfig(sourceEntity); + return processConfigRepository.save(getHandler(sourceConfig.processType()).toEntity(sourceConfig)).getId(); + }); } @Transactional @@ -98,22 +99,13 @@ public boolean deleteProcessConfig(UUID processConfigUuid) { @Transactional(readOnly = true) public List getProcessConfigs(ProcessType processType) { - switch (processType) { - case SECURITY_ANALYSIS -> { - return securityAnalysisProcessConfigRepository.findAll() - .stream() - .map(this::toPersistedProcessConfig) - .toList(); - } - default -> throw new IllegalArgumentException("Unsupported process type: " + processType); - } + return getHandler(processType).findAll().stream() + .map(this::toPersistedProcessConfig) + .toList(); } private ProcessConfig toProcessConfig(AbstractProcessConfigEntity entity) { - return switch (entity) { - case SecurityAnalysisConfigEntity sae -> securityAnalysisConfigMapper.toDto(sae); - default -> throw new IllegalArgumentException("Unsupported entity type: " + entity.getProcessType()); - }; + return getHandler(entity.getProcessType()).toDto(entity); } private PersistedProcessConfig toPersistedProcessConfig(AbstractProcessConfigEntity entity) { @@ -136,46 +128,9 @@ public Optional compareProcessConfigs(UUID uuid1, UUID throw new IllegalArgumentException("Cannot compare different process config types: " + processConfig1.processType() + " vs " + processConfig2.processType()); } - List differences = switch (processConfig1) { - case SecurityAnalysisConfig sac1 -> compareSecurityAnalysisConfigs(sac1, (SecurityAnalysisConfig) processConfig2); - default -> throw new IllegalArgumentException("Unsupported process config type: " + processConfig1.processType()); - }; - + List differences = getHandler(processConfig1.processType()).compare(processConfig1, processConfig2); boolean identical = differences.stream().allMatch(ProcessConfigFieldComparison::identical); return Optional.of(new ProcessConfigComparison(uuid1, uuid2, identical, differences)); } - - private List compareSecurityAnalysisConfigs(SecurityAnalysisConfig config1, SecurityAnalysisConfig config2) { - List differences = new ArrayList<>(); - - // Compare modifications - boolean modificationsIdentical = Objects.equals(config1.modificationUuids(), config2.modificationUuids()); - differences.add(new ProcessConfigFieldComparison( - "modifications", - modificationsIdentical, - config1.modificationUuids(), - config2.modificationUuids() - )); - - // Compare security analysis parameters - boolean securityAnalysisParametersIdentical = Objects.equals(config1.securityAnalysisParametersUuid(), config2.securityAnalysisParametersUuid()); - differences.add(new ProcessConfigFieldComparison( - "securityAnalysisParameters", - securityAnalysisParametersIdentical, - config1.securityAnalysisParametersUuid(), - config2.securityAnalysisParametersUuid() - )); - - // Compare loadflow parameters - boolean loadflowParametersIdentical = Objects.equals(config1.loadflowParametersUuid(), config2.loadflowParametersUuid()); - differences.add(new ProcessConfigFieldComparison( - "loadflowParameters", - loadflowParametersIdentical, - config1.loadflowParametersUuid(), - config2.loadflowParametersUuid() - )); - - return differences; - } } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java new file mode 100644 index 00000000..e07c72d8 --- /dev/null +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.monitor.server.services.processconfig; + +import org.gridsuite.monitor.commons.types.processconfig.SecurityAnalysisConfig; +import org.gridsuite.monitor.commons.types.processexecution.ProcessType; +import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; +import org.gridsuite.monitor.server.entities.processconfig.SecurityAnalysisConfigEntity; +import org.gridsuite.monitor.server.mappers.processconfig.SecurityAnalysisConfigMapper; +import org.gridsuite.monitor.server.repositories.SecurityAnalysisProcessConfigRepository; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Objects; + +/** + * {@link ProcessConfigHandler} for {@link ProcessType#SECURITY_ANALYSIS}. + * + * @author Franck Lecuyer + */ +@Component +public class SecurityAnalysisConfigHandler implements ProcessConfigHandler { + + private final SecurityAnalysisConfigMapper mapper; + private final SecurityAnalysisProcessConfigRepository repository; + + public SecurityAnalysisConfigHandler(SecurityAnalysisConfigMapper mapper, + SecurityAnalysisProcessConfigRepository repository) { + this.mapper = mapper; + this.repository = repository; + } + + @Override + public ProcessType getProcessType() { + return ProcessType.SECURITY_ANALYSIS; + } + + @Override + public SecurityAnalysisConfigEntity toEntity(SecurityAnalysisConfig config) { + return mapper.toEntity(config); + } + + @Override + public SecurityAnalysisConfig toDto(SecurityAnalysisConfigEntity entity) { + return mapper.toDto(entity); + } + + @Override + public void updateEntity(SecurityAnalysisConfig config, SecurityAnalysisConfigEntity entity) { + mapper.updateEntityFromDto(config, entity); + } + + @Override + public List findAll() { + return repository.findAll(); + } + + @Override + public List compare(SecurityAnalysisConfig config1, SecurityAnalysisConfig config2) { + boolean modificationsIdentical = Objects.equals(config1.modificationUuids(), config2.modificationUuids()); + boolean securityAnalysisParametersIdentical = Objects.equals(config1.securityAnalysisParametersUuid(), config2.securityAnalysisParametersUuid()); + boolean loadflowParametersIdentical = Objects.equals(config1.loadflowParametersUuid(), config2.loadflowParametersUuid()); + + return List.of( + new ProcessConfigFieldComparison("modifications", modificationsIdentical, + config1.modificationUuids(), config2.modificationUuids()), + new ProcessConfigFieldComparison("securityAnalysisParameters", securityAnalysisParametersIdentical, + config1.securityAnalysisParametersUuid(), config2.securityAnalysisParametersUuid()), + new ProcessConfigFieldComparison("loadflowParameters", loadflowParametersIdentical, + config1.loadflowParametersUuid(), config2.loadflowParametersUuid()) + ); + } +} diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java index 235b469b..b4ced17c 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java @@ -21,9 +21,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mapstruct.factory.Mappers; import org.mockito.ArgumentCaptor; -import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.Spy; import org.mockito.junit.jupiter.MockitoExtension; import java.util.List; @@ -45,16 +43,18 @@ class ProcessConfigServiceTest { @Mock private SecurityAnalysisProcessConfigRepository securityAnalysisProcessConfigRepository; - @InjectMocks private ProcessConfigService processConfigService; private SecurityAnalysisConfig securityAnalysisConfig; - @Spy private final SecurityAnalysisConfigMapper securityAnalysisConfigMapper = Mappers.getMapper(SecurityAnalysisConfigMapper.class); @BeforeEach void setUp() { + SecurityAnalysisConfigHandler securityAnalysisConfigHandler = + new SecurityAnalysisConfigHandler(securityAnalysisConfigMapper, securityAnalysisProcessConfigRepository); + processConfigService = new ProcessConfigService(processConfigRepository, List.of(securityAnalysisConfigHandler)); + securityAnalysisConfig = new SecurityAnalysisConfig( UUID.randomUUID(), List.of(UUID.randomUUID()), @@ -176,8 +176,10 @@ void duplicateSecurityAnalysisConfig() { UUID processConfigId = UUID.randomUUID(); UUID expectedNewProcessConfigId = UUID.randomUUID(); + SecurityAnalysisConfigEntity mockSourceEntity = mock(SecurityAnalysisConfigEntity.class); + when(mockSourceEntity.getProcessType()).thenReturn(ProcessType.SECURITY_ANALYSIS); when(processConfigRepository.findById(processConfigId)) - .thenReturn(Optional.of(mock(SecurityAnalysisConfigEntity.class))); + .thenReturn(Optional.of(mockSourceEntity)); when(processConfigRepository.save(any(SecurityAnalysisConfigEntity.class))) .thenAnswer(invocation -> { SecurityAnalysisConfigEntity entity = invocation.getArgument(0); From 9c1b5af3314c536c8a1ab7009a0c0cce18342c9b Mon Sep 17 00:00:00 2001 From: BOUHOURS Antoine Date: Fri, 3 Apr 2026 14:45:34 +0200 Subject: [PATCH 3/7] Fixes --- .../{ => processconfig}/ProcessConfigRepository.java | 2 +- .../SecurityAnalysisProcessConfigRepository.java | 4 ++-- .../{ => processexecution}/ProcessExecutionRepository.java | 2 +- .../server/services/processconfig/ProcessConfigService.java | 2 +- .../services/processconfig/SecurityAnalysisConfigHandler.java | 2 +- .../services/processexecution/ProcessExecutionService.java | 2 +- .../org/gridsuite/monitor/server/MonitorIntegrationTest.java | 4 ++-- .../server/repositories/ProcessExecutionRepositoryTest.java | 1 + .../services/processconfig/ProcessConfigServiceTest.java | 4 ++-- .../processexecution/ProcessExecutionServiceTest.java | 2 +- 10 files changed, 13 insertions(+), 12 deletions(-) rename monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/{ => processconfig}/ProcessConfigRepository.java (91%) rename monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/{ => processconfig}/SecurityAnalysisProcessConfigRepository.java (82%) rename monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/{ => processexecution}/ProcessExecutionRepository.java (92%) diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/ProcessConfigRepository.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/processconfig/ProcessConfigRepository.java similarity index 91% rename from monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/ProcessConfigRepository.java rename to monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/processconfig/ProcessConfigRepository.java index fa0e816f..d4c97fee 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/ProcessConfigRepository.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/processconfig/ProcessConfigRepository.java @@ -4,7 +4,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.gridsuite.monitor.server.repositories; +package org.gridsuite.monitor.server.repositories.processconfig; import org.gridsuite.monitor.server.entities.processconfig.AbstractProcessConfigEntity; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/SecurityAnalysisProcessConfigRepository.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/processconfig/SecurityAnalysisProcessConfigRepository.java similarity index 82% rename from monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/SecurityAnalysisProcessConfigRepository.java rename to monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/processconfig/SecurityAnalysisProcessConfigRepository.java index 695bb082..7a0aeefe 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/SecurityAnalysisProcessConfigRepository.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/processconfig/SecurityAnalysisProcessConfigRepository.java @@ -4,7 +4,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.gridsuite.monitor.server.repositories; +package org.gridsuite.monitor.server.repositories.processconfig; import org.gridsuite.monitor.server.entities.processconfig.SecurityAnalysisConfigEntity; import org.springframework.data.jpa.repository.JpaRepository; @@ -13,7 +13,7 @@ import java.util.UUID; /** - * @author Franck Lecuyer + * @author Antoine Bouhours */ @Repository public interface SecurityAnalysisProcessConfigRepository extends JpaRepository { diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/ProcessExecutionRepository.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/processexecution/ProcessExecutionRepository.java similarity index 92% rename from monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/ProcessExecutionRepository.java rename to monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/processexecution/ProcessExecutionRepository.java index fb91cc56..b89c4807 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/ProcessExecutionRepository.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/repositories/processexecution/ProcessExecutionRepository.java @@ -4,7 +4,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.gridsuite.monitor.server.repositories; +package org.gridsuite.monitor.server.repositories.processexecution; import org.gridsuite.monitor.server.entities.processexecution.ProcessExecutionEntity; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java index 8f76dace..2bdcd397 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java @@ -13,7 +13,7 @@ import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; import org.gridsuite.monitor.server.dto.processconfig.PersistedProcessConfig; import org.gridsuite.monitor.server.entities.processconfig.AbstractProcessConfigEntity; -import org.gridsuite.monitor.server.repositories.ProcessConfigRepository; +import org.gridsuite.monitor.server.repositories.processconfig.ProcessConfigRepository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java index e07c72d8..5214f87b 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java @@ -11,7 +11,7 @@ import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; import org.gridsuite.monitor.server.entities.processconfig.SecurityAnalysisConfigEntity; import org.gridsuite.monitor.server.mappers.processconfig.SecurityAnalysisConfigMapper; -import org.gridsuite.monitor.server.repositories.SecurityAnalysisProcessConfigRepository; +import org.gridsuite.monitor.server.repositories.processconfig.SecurityAnalysisProcessConfigRepository; import org.springframework.stereotype.Component; import java.util.List; diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processexecution/ProcessExecutionService.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processexecution/ProcessExecutionService.java index ba2fceea..195a53b4 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processexecution/ProcessExecutionService.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processexecution/ProcessExecutionService.java @@ -20,7 +20,7 @@ import org.gridsuite.monitor.server.mappers.processexecution.ProcessExecutionMapper; import org.gridsuite.monitor.server.mappers.processexecution.ProcessExecutionStepMapper; import org.gridsuite.monitor.server.messaging.NotificationService; -import org.gridsuite.monitor.server.repositories.ProcessExecutionRepository; +import org.gridsuite.monitor.server.repositories.processexecution.ProcessExecutionRepository; import org.gridsuite.monitor.server.clients.S3RestClient; import org.gridsuite.monitor.server.services.processconfig.ProcessConfigService; import org.gridsuite.monitor.server.services.result.ResultService; diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/MonitorIntegrationTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/MonitorIntegrationTest.java index 83232fbd..22b00373 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/MonitorIntegrationTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/MonitorIntegrationTest.java @@ -21,8 +21,8 @@ import org.gridsuite.monitor.server.dto.report.Severity; import org.gridsuite.monitor.server.entities.processexecution.ProcessExecutionEntity; import org.gridsuite.monitor.server.messaging.ConsumerService; -import org.gridsuite.monitor.server.repositories.ProcessConfigRepository; -import org.gridsuite.monitor.server.repositories.ProcessExecutionRepository; +import org.gridsuite.monitor.server.repositories.processconfig.ProcessConfigRepository; +import org.gridsuite.monitor.server.repositories.processexecution.ProcessExecutionRepository; import org.gridsuite.monitor.server.clients.S3RestClient; import org.gridsuite.monitor.server.services.processconfig.ProcessConfigService; import org.gridsuite.monitor.server.services.processexecution.ProcessExecutionService; diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/repositories/ProcessExecutionRepositoryTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/repositories/ProcessExecutionRepositoryTest.java index 0dd1581e..1da32c07 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/repositories/ProcessExecutionRepositoryTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/repositories/ProcessExecutionRepositoryTest.java @@ -11,6 +11,7 @@ import org.gridsuite.monitor.commons.types.processexecution.StepStatus; import org.gridsuite.monitor.server.entities.processexecution.ProcessExecutionEntity; import org.gridsuite.monitor.server.entities.processexecution.ProcessExecutionStepEntity; +import org.gridsuite.monitor.server.repositories.processexecution.ProcessExecutionRepository; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java index b4ced17c..4d4d647d 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java @@ -14,8 +14,8 @@ import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; import org.gridsuite.monitor.server.entities.processconfig.SecurityAnalysisConfigEntity; import org.gridsuite.monitor.server.mappers.processconfig.SecurityAnalysisConfigMapper; -import org.gridsuite.monitor.server.repositories.ProcessConfigRepository; -import org.gridsuite.monitor.server.repositories.SecurityAnalysisProcessConfigRepository; +import org.gridsuite.monitor.server.repositories.processconfig.ProcessConfigRepository; +import org.gridsuite.monitor.server.repositories.processconfig.SecurityAnalysisProcessConfigRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processexecution/ProcessExecutionServiceTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processexecution/ProcessExecutionServiceTest.java index 9360b82a..4757255d 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processexecution/ProcessExecutionServiceTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processexecution/ProcessExecutionServiceTest.java @@ -25,7 +25,7 @@ import org.gridsuite.monitor.server.mappers.processexecution.ProcessExecutionMapper; import org.gridsuite.monitor.server.mappers.processexecution.ProcessExecutionStepMapper; import org.gridsuite.monitor.server.messaging.NotificationService; -import org.gridsuite.monitor.server.repositories.ProcessExecutionRepository; +import org.gridsuite.monitor.server.repositories.processexecution.ProcessExecutionRepository; import org.gridsuite.monitor.server.clients.S3RestClient; import org.gridsuite.monitor.server.services.processconfig.ProcessConfigService; import org.gridsuite.monitor.server.services.result.ResultService; From b93a81ee68fc13b8bb6e89abf5eb61d590479f33 Mon Sep 17 00:00:00 2001 From: BOUHOURS Antoine Date: Fri, 3 Apr 2026 14:49:56 +0200 Subject: [PATCH 4/7] Fixes --- .../processconfig/ProcessConfigHandler.java | 22 ------------------- .../SecurityAnalysisConfigHandler.java | 4 +--- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java index 473f81f1..ce050865 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java @@ -13,39 +13,17 @@ import java.util.List; -/** - * Handler for a specific {@link ProcessConfig} type. Encapsulates all type-specific - * logic (mapping, persistence, comparison) so that {@link ProcessConfigService} remains - * free of per-type switch statements. Add a new Spring {@code @Component} implementation - * of this interface for every new config type. - * - * @param the DTO type (must implement {@link ProcessConfig}) - * @param the JPA entity type (must extend {@link AbstractProcessConfigEntity}) - */ public interface ProcessConfigHandler { - /** Returns the {@link ProcessType} this handler is responsible for. */ ProcessType getProcessType(); - /** Converts a DTO to a new (unsaved) entity. The entity {@code id} must be left null. */ E toEntity(C config); - /** Converts an entity to its DTO representation. */ C toDto(E entity); - /** - * Applies the fields of {@code config} onto {@code entity} in place. - * The entity {@code id} must not be modified. - */ void updateEntity(C config, E entity); - /** Returns all persisted entities of this type. */ List findAll(); - /** - * Compares two DTOs of this type field by field. - * - * @return a list of {@link ProcessConfigFieldComparison} entries, one per compared field - */ List compare(C config1, C config2); } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java index 5214f87b..604247f5 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java @@ -18,9 +18,7 @@ import java.util.Objects; /** - * {@link ProcessConfigHandler} for {@link ProcessType#SECURITY_ANALYSIS}. - * - * @author Franck Lecuyer + * @author Antoine Bouhours */ @Component public class SecurityAnalysisConfigHandler implements ProcessConfigHandler { From 417c9396596669aefb33ddf48d71bbaf5b8a8305 Mon Sep 17 00:00:00 2001 From: BOUHOURS Antoine Date: Fri, 3 Apr 2026 15:02:48 +0200 Subject: [PATCH 5/7] Change compare implem --- .../types/processconfig/ProcessConfig.java | 2 ++ .../ProcessConfigFieldComparison.java | 5 +---- .../processconfig/SecurityAnalysisConfig.java | 17 +++++++++++++++++ .../processconfig/ProcessConfigComparison.java | 1 + .../processconfig/ProcessConfigHandler.java | 3 --- .../processconfig/ProcessConfigService.java | 4 ++-- .../SecurityAnalysisConfigHandler.java | 18 ------------------ .../ProcessConfigControllerTest.java | 2 +- .../ProcessConfigServiceTest.java | 2 +- 9 files changed, 25 insertions(+), 29 deletions(-) rename {monitor-server/src/main/java/org/gridsuite/monitor/server/dto => monitor-commons/src/main/java/org/gridsuite/monitor/commons/types}/processconfig/ProcessConfigFieldComparison.java (74%) diff --git a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/ProcessConfig.java b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/ProcessConfig.java index d5176671..8c55aadf 100644 --- a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/ProcessConfig.java +++ b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/ProcessConfig.java @@ -27,4 +27,6 @@ public interface ProcessConfig { ProcessType processType(); List modificationUuids(); + + List compareWith(ProcessConfig other); } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/dto/processconfig/ProcessConfigFieldComparison.java b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/ProcessConfigFieldComparison.java similarity index 74% rename from monitor-server/src/main/java/org/gridsuite/monitor/server/dto/processconfig/ProcessConfigFieldComparison.java rename to monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/ProcessConfigFieldComparison.java index 71fd2310..8163298e 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/dto/processconfig/ProcessConfigFieldComparison.java +++ b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/ProcessConfigFieldComparison.java @@ -4,14 +4,11 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.gridsuite.monitor.server.dto.processconfig; - -import io.swagger.v3.oas.annotations.media.Schema; +package org.gridsuite.monitor.commons.types.processconfig; /** * @author Franck Lecuyer */ -@Schema(description = "Field comparison result") public record ProcessConfigFieldComparison( String field, boolean identical, diff --git a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/SecurityAnalysisConfig.java b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/SecurityAnalysisConfig.java index bda1e699..ad73d2c1 100644 --- a/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/SecurityAnalysisConfig.java +++ b/monitor-commons/src/main/java/org/gridsuite/monitor/commons/types/processconfig/SecurityAnalysisConfig.java @@ -9,6 +9,7 @@ import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import java.util.List; +import java.util.Objects; import java.util.UUID; /** @@ -23,4 +24,20 @@ public record SecurityAnalysisConfig( public ProcessType processType() { return ProcessType.SECURITY_ANALYSIS; } + + @Override + public List compareWith(ProcessConfig other) { + SecurityAnalysisConfig o = (SecurityAnalysisConfig) other; + return List.of( + new ProcessConfigFieldComparison("modifications", + Objects.equals(modificationUuids, o.modificationUuids), + modificationUuids, o.modificationUuids), + new ProcessConfigFieldComparison("securityAnalysisParameters", + Objects.equals(securityAnalysisParametersUuid, o.securityAnalysisParametersUuid), + securityAnalysisParametersUuid, o.securityAnalysisParametersUuid), + new ProcessConfigFieldComparison("loadflowParameters", + Objects.equals(loadflowParametersUuid, o.loadflowParametersUuid), + loadflowParametersUuid, o.loadflowParametersUuid) + ); + } } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/dto/processconfig/ProcessConfigComparison.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/dto/processconfig/ProcessConfigComparison.java index 0b7fd42b..cf1a657a 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/dto/processconfig/ProcessConfigComparison.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/dto/processconfig/ProcessConfigComparison.java @@ -7,6 +7,7 @@ package org.gridsuite.monitor.server.dto.processconfig; import io.swagger.v3.oas.annotations.media.Schema; +import org.gridsuite.monitor.commons.types.processconfig.ProcessConfigFieldComparison; import java.util.List; import java.util.UUID; diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java index ce050865..78a88ce0 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java @@ -8,7 +8,6 @@ import org.gridsuite.monitor.commons.types.processconfig.ProcessConfig; import org.gridsuite.monitor.commons.types.processexecution.ProcessType; -import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; import org.gridsuite.monitor.server.entities.processconfig.AbstractProcessConfigEntity; import java.util.List; @@ -24,6 +23,4 @@ public interface ProcessConfigHandler findAll(); - - List compare(C config1, C config2); } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java index 2bdcd397..fc640621 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java @@ -7,10 +7,10 @@ package org.gridsuite.monitor.server.services.processconfig; import org.gridsuite.monitor.commons.types.processconfig.ProcessConfig; +import org.gridsuite.monitor.commons.types.processconfig.ProcessConfigFieldComparison; import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import org.gridsuite.monitor.server.dto.processconfig.MetadataInfos; import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigComparison; -import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; import org.gridsuite.monitor.server.dto.processconfig.PersistedProcessConfig; import org.gridsuite.monitor.server.entities.processconfig.AbstractProcessConfigEntity; import org.gridsuite.monitor.server.repositories.processconfig.ProcessConfigRepository; @@ -128,7 +128,7 @@ public Optional compareProcessConfigs(UUID uuid1, UUID throw new IllegalArgumentException("Cannot compare different process config types: " + processConfig1.processType() + " vs " + processConfig2.processType()); } - List differences = getHandler(processConfig1.processType()).compare(processConfig1, processConfig2); + List differences = processConfig1.compareWith(processConfig2); boolean identical = differences.stream().allMatch(ProcessConfigFieldComparison::identical); return Optional.of(new ProcessConfigComparison(uuid1, uuid2, identical, differences)); diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java index 604247f5..8d723777 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/SecurityAnalysisConfigHandler.java @@ -8,14 +8,12 @@ import org.gridsuite.monitor.commons.types.processconfig.SecurityAnalysisConfig; import org.gridsuite.monitor.commons.types.processexecution.ProcessType; -import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; import org.gridsuite.monitor.server.entities.processconfig.SecurityAnalysisConfigEntity; import org.gridsuite.monitor.server.mappers.processconfig.SecurityAnalysisConfigMapper; import org.gridsuite.monitor.server.repositories.processconfig.SecurityAnalysisProcessConfigRepository; import org.springframework.stereotype.Component; import java.util.List; -import java.util.Objects; /** * @author Antoine Bouhours @@ -56,20 +54,4 @@ public void updateEntity(SecurityAnalysisConfig config, SecurityAnalysisConfigEn public List findAll() { return repository.findAll(); } - - @Override - public List compare(SecurityAnalysisConfig config1, SecurityAnalysisConfig config2) { - boolean modificationsIdentical = Objects.equals(config1.modificationUuids(), config2.modificationUuids()); - boolean securityAnalysisParametersIdentical = Objects.equals(config1.securityAnalysisParametersUuid(), config2.securityAnalysisParametersUuid()); - boolean loadflowParametersIdentical = Objects.equals(config1.loadflowParametersUuid(), config2.loadflowParametersUuid()); - - return List.of( - new ProcessConfigFieldComparison("modifications", modificationsIdentical, - config1.modificationUuids(), config2.modificationUuids()), - new ProcessConfigFieldComparison("securityAnalysisParameters", securityAnalysisParametersIdentical, - config1.securityAnalysisParametersUuid(), config2.securityAnalysisParametersUuid()), - new ProcessConfigFieldComparison("loadflowParameters", loadflowParametersIdentical, - config1.loadflowParametersUuid(), config2.loadflowParametersUuid()) - ); - } } diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java index f33196ec..2fe60eb9 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/ProcessConfigControllerTest.java @@ -13,7 +13,7 @@ import org.gridsuite.monitor.commons.types.processconfig.SecurityAnalysisConfig; import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigComparison; -import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; +import org.gridsuite.monitor.commons.types.processconfig.ProcessConfigFieldComparison; import org.gridsuite.monitor.server.services.processconfig.ProcessConfigService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java index 4d4d647d..2d551f86 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigServiceTest.java @@ -11,7 +11,7 @@ import org.gridsuite.monitor.commons.types.processconfig.SecurityAnalysisConfig; import org.gridsuite.monitor.commons.types.processexecution.ProcessType; import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigComparison; -import org.gridsuite.monitor.server.dto.processconfig.ProcessConfigFieldComparison; +import org.gridsuite.monitor.commons.types.processconfig.ProcessConfigFieldComparison; import org.gridsuite.monitor.server.entities.processconfig.SecurityAnalysisConfigEntity; import org.gridsuite.monitor.server.mappers.processconfig.SecurityAnalysisConfigMapper; import org.gridsuite.monitor.server.repositories.processconfig.ProcessConfigRepository; From 7889b1b577f2b02a2311428ee22bbf87a9278835 Mon Sep 17 00:00:00 2001 From: BOUHOURS Antoine Date: Fri, 3 Apr 2026 15:33:14 +0200 Subject: [PATCH 6/7] Improve generics? --- .../processconfig/ProcessConfigService.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java index fc640621..c273c624 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigService.java @@ -21,6 +21,7 @@ import java.util.Map; import java.util.Optional; import java.util.UUID; +import java.util.function.Function; import java.util.stream.Collectors; /** @@ -29,24 +30,25 @@ @Service public class ProcessConfigService { private final ProcessConfigRepository processConfigRepository; - private final Map> handlers; + private final Map> handlers; - @SuppressWarnings("unchecked") public ProcessConfigService(ProcessConfigRepository processConfigRepository, List> handlers) { this.processConfigRepository = processConfigRepository; - this.handlers = handlers.stream().collect(Collectors.toMap( + this.handlers = handlers.stream().collect(Collectors.toUnmodifiableMap( ProcessConfigHandler::getProcessType, - h -> (ProcessConfigHandler) h + Function.identity() )); } - private ProcessConfigHandler getHandler(ProcessType processType) { - ProcessConfigHandler handler = handlers.get(processType); + @SuppressWarnings("unchecked") + private ProcessConfigHandler getHandler(ProcessType processType) { + ProcessConfigHandler handler = handlers.get(processType); if (handler == null) { throw new IllegalArgumentException("Unsupported process config type: " + processType); } - return handler; + // Safe: the service always dispatches using config.processType(), which matches the handler's registered type + return (ProcessConfigHandler) handler; } @Transactional From 297e3720e173396bbb57b5e9392b1730067d4818 Mon Sep 17 00:00:00 2001 From: BOUHOURS Antoine Date: Fri, 3 Apr 2026 15:41:38 +0200 Subject: [PATCH 7/7] Improve generics? --- .../server/services/processconfig/ProcessConfigHandler.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java index 78a88ce0..47ec02f1 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/processconfig/ProcessConfigHandler.java @@ -12,6 +12,9 @@ import java.util.List; +/** + * @author Antoine Bouhours + */ public interface ProcessConfigHandler { ProcessType getProcessType();