Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* 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.commons;

import java.util.UUID;

/**
* @author Franck Lecuyer <franck.lecuyer at rte-france.com>
*/
public record PersistedProcessConfig(
UUID id,
ProcessConfig processConfig
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ public record SecurityAnalysisConfig(
List<String> contingencies,
List<UUID> modificationUuids
) implements ProcessConfig {

@Override
public ProcessType processType() {
return ProcessType.SECURITY_ANALYSIS;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.gridsuite.monitor.commons.PersistedProcessConfig;
import org.gridsuite.monitor.commons.ProcessConfig;
import org.gridsuite.monitor.commons.ProcessType;
import org.gridsuite.monitor.server.services.ProcessConfigService;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
Expand All @@ -22,8 +24,10 @@
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Optional;
import java.util.UUID;

Expand Down Expand Up @@ -55,9 +59,9 @@ public ResponseEntity<UUID> createProcessConfig(@RequestBody ProcessConfig proce
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "process config was returned"),
@ApiResponse(responseCode = "404", description = "process config was not found")})
public ResponseEntity<ProcessConfig> getProcessConfig(
public ResponseEntity<PersistedProcessConfig> getProcessConfig(
@Parameter(description = "process config UUID") @PathVariable("uuid") UUID processConfigUuid) {
Optional<ProcessConfig> processConfig = processConfigService.getProcessConfig(processConfigUuid);
Optional<PersistedProcessConfig> processConfig = processConfigService.getProcessConfig(processConfigUuid);
return processConfig.map(config -> ResponseEntity.ok().body(config)).orElseGet(() -> ResponseEntity.notFound().build());
}

Expand Down Expand Up @@ -85,4 +89,14 @@ public ResponseEntity<Void> deleteProcessConfig(
ResponseEntity.ok().build() :
ResponseEntity.notFound().build();
}

@GetMapping(value = "", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Get all process configs of a given type")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "The process configs of the given type were returned")})
public ResponseEntity<List<PersistedProcessConfig>> getProcessConfigs(
@Parameter(description = "Process type") @RequestParam(name = "processType") ProcessType processType) {
List<PersistedProcessConfig> processConfigs = processConfigService.getProcessConfigs(processType);
return ResponseEntity.ok().body(processConfigs);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
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;
Expand Down Expand Up @@ -43,7 +45,7 @@
@AllArgsConstructor
@Getter
@Setter
public abstract class AbstractProcessConfigEntity {
public class ProcessConfigEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
Expand All @@ -57,7 +59,9 @@ public abstract class AbstractProcessConfigEntity {
@OrderColumn(name = "pos_modifications")
private List<UUID> modificationUuids;

public abstract ProcessType getType();
@Enumerated(EnumType.STRING)
@Column(name = "process_type", insertable = false, updatable = false)
private ProcessType processType;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.gridsuite.monitor.commons.ProcessType;

import java.util.List;
import java.util.UUID;
Expand All @@ -37,7 +36,7 @@
@AllArgsConstructor
@Getter
@Setter
public class SecurityAnalysisConfigEntity extends AbstractProcessConfigEntity {
public class SecurityAnalysisConfigEntity extends ProcessConfigEntity {
@Column(name = "parameters_uuid")
private UUID parametersUuid;

Expand All @@ -48,13 +47,4 @@ public class SecurityAnalysisConfigEntity extends AbstractProcessConfigEntity {
@Column(name = "contingency")
@OrderColumn(name = "pos_contingencies")
private List<String> contingencies;

@Override
public ProcessType getType() {
return ProcessType.SECURITY_ANALYSIS;
}
}




Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
*/
package org.gridsuite.monitor.server.mapper;

import org.gridsuite.monitor.commons.PersistedProcessConfig;
import org.gridsuite.monitor.commons.ProcessType;
import org.gridsuite.monitor.commons.SecurityAnalysisConfig;
import org.gridsuite.monitor.server.entities.SecurityAnalysisConfigEntity;

Expand All @@ -16,16 +18,17 @@
public class SecurityAnalysisConfigMapper {
public static SecurityAnalysisConfigEntity toEntity(SecurityAnalysisConfig dto) {
SecurityAnalysisConfigEntity entity = new SecurityAnalysisConfigEntity();
entity.setProcessType(ProcessType.SECURITY_ANALYSIS);
update(entity, dto);
return entity;
}

public static SecurityAnalysisConfig toDto(SecurityAnalysisConfigEntity entity) {
return new SecurityAnalysisConfig(
public static PersistedProcessConfig toDto(SecurityAnalysisConfigEntity entity) {
return new PersistedProcessConfig(entity.getId(), new SecurityAnalysisConfig(
entity.getParametersUuid(),
entity.getContingencies(),
entity.getModificationUuids()
);
));
}

public static void update(SecurityAnalysisConfigEntity entity, SecurityAnalysisConfig dto) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@
*/
package org.gridsuite.monitor.server.repositories;

import org.gridsuite.monitor.server.entities.AbstractProcessConfigEntity;
import org.gridsuite.monitor.commons.ProcessType;
import org.gridsuite.monitor.server.entities.ProcessConfigEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.UUID;

/**
* @author Franck Lecuyer <franck.lecuyer at rte-france.com>
*/
@Repository
public interface ProcessConfigRepository extends JpaRepository<AbstractProcessConfigEntity, UUID> {
public interface ProcessConfigRepository extends JpaRepository<ProcessConfigEntity, UUID> {
List<ProcessConfigEntity> findAllByProcessType(ProcessType processType);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@
*/
package org.gridsuite.monitor.server.services;

import org.gridsuite.monitor.commons.PersistedProcessConfig;
import org.gridsuite.monitor.commons.ProcessConfig;
import org.gridsuite.monitor.commons.ProcessType;
import org.gridsuite.monitor.commons.SecurityAnalysisConfig;
import org.gridsuite.monitor.server.entities.AbstractProcessConfigEntity;
import org.gridsuite.monitor.server.entities.ProcessConfigEntity;
import org.gridsuite.monitor.server.entities.SecurityAnalysisConfigEntity;
import org.gridsuite.monitor.server.mapper.SecurityAnalysisConfigMapper;
import org.gridsuite.monitor.server.repositories.ProcessConfigRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;
import java.util.UUID;

Expand All @@ -31,28 +34,28 @@ public ProcessConfigService(ProcessConfigRepository processConfigRepository) {

@Transactional
public UUID createProcessConfig(ProcessConfig processConfig) {
AbstractProcessConfigEntity entity = switch (processConfig) {
case SecurityAnalysisConfig sac -> SecurityAnalysisConfigMapper.toEntity(sac);
switch (processConfig) {
case SecurityAnalysisConfig sac -> {
return processConfigRepository.save(SecurityAnalysisConfigMapper.toEntity(sac)).getId();
}
default -> throw new IllegalArgumentException("Unsupported process config type: " + processConfig.processType());
};
return processConfigRepository.save(entity).getId();
}
}

@Transactional(readOnly = true)
public Optional<ProcessConfig> getProcessConfig(UUID processConfigUuid) {
public Optional<PersistedProcessConfig> getProcessConfig(UUID processConfigUuid) {
return processConfigRepository.findById(processConfigUuid).flatMap(entity -> switch (entity) {
case SecurityAnalysisConfigEntity sae ->
Optional.of((ProcessConfig) SecurityAnalysisConfigMapper.toDto(sae));
default -> throw new IllegalArgumentException("Unsupported entity type: " + entity.getType());
case SecurityAnalysisConfigEntity sae -> Optional.of(SecurityAnalysisConfigMapper.toDto(sae));
default -> throw new IllegalArgumentException("Unsupported entity type: " + entity.getProcessType());
});
}

@Transactional
public boolean updateProcessConfig(UUID processConfigUuid, ProcessConfig processConfig) {
return processConfigRepository.findById(processConfigUuid)
.map(entity -> {
if (entity.getType() != processConfig.processType()) {
throw new IllegalArgumentException("Process config type mismatch : " + entity.getType());
if (entity.getProcessType() != processConfig.processType()) {
throw new IllegalArgumentException("Process config type mismatch : " + entity.getProcessType());
}
switch (processConfig) {
case SecurityAnalysisConfig sac ->
Expand All @@ -72,4 +75,13 @@ public boolean deleteProcessConfig(UUID processConfigUuid) {
}
return false;
}

@Transactional(readOnly = true)
public List<PersistedProcessConfig> getProcessConfigs(ProcessType processType) {
List<ProcessConfigEntity> processConfigs = processConfigRepository.findAllByProcessType(processType);
return processConfigs.stream().map(entity -> switch (entity) {
case SecurityAnalysisConfigEntity sae -> SecurityAnalysisConfigMapper.toDto(sae);
default -> throw new IllegalArgumentException("Unsupported entity type: " + entity.getProcessType());
}).toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,9 @@ void processConfigIT() {
UUID configId = configService.createProcessConfig(securityAnalysisConfig);
assertThat(processConfigRepository.findById(configId)).isNotEmpty();

Optional<ProcessConfig> config = configService.getProcessConfig(configId);
Optional<PersistedProcessConfig> config = configService.getProcessConfig(configId);
assertThat(config).isNotEmpty();
assertThat(config.get()).usingRecursiveComparison().isEqualTo(securityAnalysisConfig);
assertThat(config.get().processConfig()).usingRecursiveComparison().isEqualTo(securityAnalysisConfig);

UUID updatedParametersUuid = UUID.randomUUID();
UUID updatedModificationUuid = UUID.randomUUID();
Expand All @@ -257,13 +257,72 @@ void processConfigIT() {
);
boolean updated = configService.updateProcessConfig(configId, updatedSecurityAnalysisConfig);
assertThat(updated).isTrue();
Optional<ProcessConfig> updatedConfig = configService.getProcessConfig(configId);
Optional<PersistedProcessConfig> updatedConfig = configService.getProcessConfig(configId);
assertThat(updatedConfig).isNotEmpty();
assertThat(updatedConfig.get()).usingRecursiveComparison().isEqualTo(updatedSecurityAnalysisConfig);
assertThat(updatedConfig.get().processConfig()).usingRecursiveComparison().isEqualTo(updatedSecurityAnalysisConfig);

boolean deleted = configService.deleteProcessConfig(configId);
assertThat(deleted).isTrue();
Optional<ProcessConfig> deletedConfig = configService.getProcessConfig(configId);
Optional<PersistedProcessConfig> deletedConfig = configService.getProcessConfig(configId);
assertThat(deletedConfig).isEmpty();
}

@Test
void processConfigsIT() {
UUID parametersUuid1 = UUID.randomUUID();
UUID modificationUuid1 = UUID.randomUUID();
SecurityAnalysisConfig securityAnalysisConfig1 = new SecurityAnalysisConfig(
parametersUuid1,
List.of("contingency1", "contingency2"),
List.of(modificationUuid1)
);
UUID configId1 = configService.createProcessConfig(securityAnalysisConfig1);
assertThat(processConfigRepository.findById(configId1)).isNotEmpty();

UUID parametersUuid2 = UUID.randomUUID();
UUID modificationUuid2 = UUID.randomUUID();
SecurityAnalysisConfig securityAnalysisConfig2 = new SecurityAnalysisConfig(
parametersUuid2,
List.of("contingency3", "contingency4"),
List.of(modificationUuid2)
);
UUID configId2 = configService.createProcessConfig(securityAnalysisConfig2);
assertThat(processConfigRepository.findById(configId2)).isNotEmpty();

List<PersistedProcessConfig> processConfigs = configService.getProcessConfigs(ProcessType.SECURITY_ANALYSIS);
assertThat(processConfigs).hasSize(2);

PersistedProcessConfig retrievedConfig1 = processConfigs.stream()
.filter(c -> c.id().equals(configId1))
.findFirst()
.orElseThrow();
SecurityAnalysisConfig retrievedSecurityAnalysisConfig1 = (SecurityAnalysisConfig) retrievedConfig1.processConfig();

PersistedProcessConfig retrievedConfig2 = processConfigs.stream()
.filter(c -> c.id().equals(configId2))
.findFirst()
.orElseThrow();
SecurityAnalysisConfig retrievedSecurityAnalysisConfig2 = (SecurityAnalysisConfig) retrievedConfig2.processConfig();

assertThat(retrievedSecurityAnalysisConfig1.parametersUuid()).isEqualTo(parametersUuid1);
assertThat(retrievedSecurityAnalysisConfig1.contingencies()).isEqualTo(List.of("contingency1", "contingency2"));
assertThat(retrievedSecurityAnalysisConfig1.modificationUuids()).isEqualTo(List.of(modificationUuid1));

assertThat(retrievedSecurityAnalysisConfig2.parametersUuid()).isEqualTo(parametersUuid2);
assertThat(retrievedSecurityAnalysisConfig2.contingencies()).isEqualTo(List.of("contingency3", "contingency4"));
assertThat(retrievedSecurityAnalysisConfig2.modificationUuids()).isEqualTo(List.of(modificationUuid2));

boolean deleted = configService.deleteProcessConfig(configId1);
assertThat(deleted).isTrue();

List<PersistedProcessConfig> remainingConfigs = configService.getProcessConfigs(ProcessType.SECURITY_ANALYSIS);
assertThat(remainingConfigs).hasSize(1);
assertThat(remainingConfigs.get(0).processConfig().processType()).isEqualTo(ProcessType.SECURITY_ANALYSIS);

boolean deletedSecond = configService.deleteProcessConfig(configId2);
assertThat(deletedSecond).isTrue();

List<PersistedProcessConfig> noConfigs = configService.getProcessConfigs(ProcessType.SECURITY_ANALYSIS);
assertThat(noConfigs).isEmpty();
}
}
Loading
Loading