Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
27efb12
SA results: add locationId to entities and dtos.
AAJELLAL Dec 31, 2024
ea42413
Merge branch 'main' of https://github.com/gridsuite/security-analysis…
AAJELLAL Dec 31, 2024
6f0ead6
Merge branch 'main' into add-locationId-to-sa-result
AAJELLAL Jan 7, 2025
0f2fdfb
SA results: add locationId to the allowed sort properties.
AAJELLAL Jan 8, 2025
68415ca
SA results: add changelog.
AAJELLAL Jan 9, 2025
9416a75
Merge branch 'main' into add-locationId-to-sa-result
AAJELLAL Jan 9, 2025
0910c7d
Add tests.
AAJELLAL Jan 13, 2025
a3d255b
Merge branch 'add-locationId-to-sa-result' of https://github.com/grid…
AAJELLAL Jan 13, 2025
94905a7
Merge branch 'main' of https://github.com/gridsuite/security-analysis…
Jan 27, 2025
1ee3328
Merge branch 'main' of https://github.com/gridsuite/security-analysis…
Feb 18, 2025
45db592
Change the DB schema in order to add locationId.
AAJELLAL Feb 24, 2025
845bc0d
Merge branch 'add-locationId-to-sa-result' of https://github.com/grid…
AAJELLAL Feb 24, 2025
eac35fd
Merge branch 'main' of https://github.com/gridsuite/security-analysis…
AAJELLAL Feb 24, 2025
7afb451
Add changelog
AAJELLAL Feb 24, 2025
6034834
Merge branch 'main' of https://github.com/gridsuite/security-analysis…
Feb 26, 2025
6319c1b
Clean upd tests.
AAJELLAL Feb 26, 2025
ea814a3
Merge branch 'main' of https://github.com/gridsuite/security-analysis…
AAJELLAL Feb 26, 2025
22bdfbf
Merge branch 'add-locationId-to-sa-result' of https://github.com/grid…
AAJELLAL Feb 26, 2025
d030431
update tests.
AAJELLAL Feb 26, 2025
38cef29
update tests.
AAJELLAL Feb 26, 2025
de51e12
Merge branch 'main' of https://github.com/gridsuite/security-analysis…
Feb 27, 2025
97d4a9c
Merge branch 'main' into add-locationId-to-sa-result
AAJELLAL May 26, 2025
6dfeb75
Merge branch 'main' into add-locationId-to-sa-result
AAJELLAL May 28, 2025
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
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -256,4 +256,4 @@
<scope>test</scope>
</dependency>
</dependencies>
</project>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class LimitViolationDTO {
private double limitReduction;
private double value;
private Double loading;
private String locationId;

public static LimitViolationDTO toDto(AbstractLimitViolationEntity limitViolation) {
return LimitViolationDTO.builder()
Expand All @@ -37,11 +38,13 @@ public static LimitViolationDTO toDto(AbstractLimitViolationEntity limitViolatio
.limitReduction(limitViolation.getLimitReduction())
.value(limitViolation.getValue())
.loading(limitViolation.getLoading())
.locationId(limitViolation.getLocationId())
.build();
}

public List<String> toCsvRow(Map<String, String> translations) {
List<String> csvRow = new ArrayList<>();
csvRow.add(this.getLocationId());
csvRow.add(this.getLimitType() != null ? CsvExportUtils.translate(this.getLimitType().name(), translations) : "");
csvRow.add(CsvExportUtils.replaceNullWithEmptyString(CsvExportUtils.translate(this.getLimitName(), translations)));
csvRow.add(Double.toString(this.getLimit()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldNameConstants;
import org.gridsuite.securityanalysis.server.entities.PreContingencyLimitViolationEntity;

import java.util.List;
Expand All @@ -21,6 +22,7 @@
@AllArgsConstructor
@NoArgsConstructor
@Builder
@FieldNameConstants
public class PreContingencyLimitViolationResultDTO {

private String subjectId;
Expand All @@ -31,7 +33,6 @@ public static PreContingencyLimitViolationResultDTO toDto(PreContingencyLimitVio
String subjectId = preContingencyLimitViolation.getSubjectLimitViolation() != null
? preContingencyLimitViolation.getSubjectLimitViolation().getSubjectId()
: null;

return PreContingencyLimitViolationResultDTO.builder()
.subjectId(subjectId)
.status(preContingencyLimitViolation.getResult().getPreContingencyStatus())
Expand All @@ -40,7 +41,7 @@ public static PreContingencyLimitViolationResultDTO toDto(PreContingencyLimitVio
}

public List<String> toCsvRow(Map<String, String> translations) {
List<String> csvRow = List.of(this.getSubjectId());
List<String> csvRow = List.of();

if (this.getLimitViolation() != null) {
return Stream.concat(csvRow.stream(), this.getLimitViolation().toCsvRow(translations).stream()).toList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,12 @@
@Builder
public class SubjectLimitViolationDTO {
private String subjectId;

private LimitViolationDTO limitViolation;

public static SubjectLimitViolationDTO toDto(ContingencyLimitViolationEntity limitViolation) {
String subjectId = limitViolation.getSubjectLimitViolation() != null
? limitViolation.getSubjectLimitViolation().getSubjectId()
: null;

return SubjectLimitViolationDTO.builder()
.subjectId(subjectId)
.limitViolation(LimitViolationDTO.toDto(limitViolation))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
@NoArgsConstructor
public class SubjectLimitViolationResultDTO {
private String subjectId;

private List<ContingencyLimitViolationDTO> contingencies;

public static SubjectLimitViolationResultDTO toDto(SubjectLimitViolationEntity subjectLimitViolation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ public abstract class AbstractLimitViolationEntity {
@Column(name = "loading")
private Double loading;

@Column
private String locationId;

public static Double computeLoading(LimitViolation limitViolation) {
return LimitViolationType.CURRENT.equals(limitViolation.getLimitType())
? 100 * limitViolation.getValue() / limitViolation.getLimit()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package org.gridsuite.securityanalysis.server.entities;

import com.powsybl.iidm.network.Network;
import com.powsybl.security.results.PostContingencyResult;
import jakarta.persistence.*;
import lombok.Getter;
Expand Down Expand Up @@ -41,7 +42,6 @@ public ContingencyEntity(String contingencyId, String status, List<ContingencyEl
private UUID uuid;

private String contingencyId;

@Setter
@ManyToOne(fetch = FetchType.LAZY)
private SecurityAnalysisResultEntity result;
Expand All @@ -64,11 +64,11 @@ private void setContingencyLimitViolations(List<ContingencyLimitViolationEntity>
}
}

public static ContingencyEntity toEntity(PostContingencyResult postContingencyResult, Map<String, SubjectLimitViolationEntity> subjectLimitViolationsBySubjectId) {
public static ContingencyEntity toEntity(Network network, PostContingencyResult postContingencyResult, Map<String, SubjectLimitViolationEntity> subjectLimitViolationsBySubjectId) {
List<ContingencyElementEmbeddable> contingencyElements = postContingencyResult.getContingency().getElements().stream().map(contingencyElement -> ContingencyElementEmbeddable.toEntity(contingencyElement)).collect(Collectors.toList());

List<ContingencyLimitViolationEntity> contingencyLimitViolations = postContingencyResult.getLimitViolationsResult().getLimitViolations().stream()
.map(limitViolation -> ContingencyLimitViolationEntity.toEntity(limitViolation, subjectLimitViolationsBySubjectId.get(limitViolation.getSubjectId())))
.map(limitViolation -> ContingencyLimitViolationEntity.toEntity(network, limitViolation, subjectLimitViolationsBySubjectId.get(limitViolation.getSubjectId())))
.collect(Collectors.toList());
return new ContingencyEntity(postContingencyResult.getContingency().getId(), postContingencyResult.getStatus().name(), contingencyElements, contingencyLimitViolations);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
*/
package org.gridsuite.securityanalysis.server.entities;

import com.powsybl.iidm.network.Network;
import com.powsybl.security.LimitViolation;
import com.powsybl.ws.commons.computation.utils.ComputationResultUtils;
import jakarta.persistence.*;
import lombok.*;
import lombok.experimental.FieldNameConstants;
Expand All @@ -30,7 +32,7 @@ public class ContingencyLimitViolationEntity extends AbstractLimitViolationEntit
@Setter
private ContingencyEntity contingency;

public static ContingencyLimitViolationEntity toEntity(LimitViolation limitViolation, SubjectLimitViolationEntity subjectLimitViolation) {
public static ContingencyLimitViolationEntity toEntity(Network network, LimitViolation limitViolation, SubjectLimitViolationEntity subjectLimitViolation) {
ContingencyLimitViolationEntity contingencyLimitViolationEntity = ContingencyLimitViolationEntity.builder()
.limit(limitViolation.getLimit())
.limitName(limitViolation.getLimitName())
Expand All @@ -40,6 +42,7 @@ public static ContingencyLimitViolationEntity toEntity(LimitViolation limitViola
.value(limitViolation.getValue())
.side(limitViolation.getSide())
.loading(computeLoading(limitViolation))
.locationId(ComputationResultUtils.getViolationLocationId(limitViolation, network))
.subjectLimitViolation(subjectLimitViolation)
.build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@
*/
package org.gridsuite.securityanalysis.server.entities;

import com.powsybl.iidm.network.Network;
import com.powsybl.security.LimitViolation;
import com.powsybl.security.results.PreContingencyResult;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import com.powsybl.ws.commons.computation.utils.ComputationResultUtils;
import jakarta.persistence.*;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand All @@ -35,16 +34,15 @@
@FieldNameConstants
@Table(name = "pre_contingency_limit_violation")
public class PreContingencyLimitViolationEntity extends AbstractLimitViolationEntity {

@ManyToOne(fetch = FetchType.LAZY)
@Setter
SecurityAnalysisResultEntity result;

public static List<PreContingencyLimitViolationEntity> toEntityList(PreContingencyResult preContingencyResult, Map<String, SubjectLimitViolationEntity> subjectLimitViolationsBySubjectId) {
return preContingencyResult.getLimitViolationsResult().getLimitViolations().stream().map(limitViolation -> toEntity(limitViolation, subjectLimitViolationsBySubjectId.get(limitViolation.getSubjectId()))).collect(Collectors.toList());
public static List<PreContingencyLimitViolationEntity> toEntityList(Network network, PreContingencyResult preContingencyResult, Map<String, SubjectLimitViolationEntity> subjectLimitViolationsBySubjectId) {
return preContingencyResult.getLimitViolationsResult().getLimitViolations().stream().map(limitViolation -> toEntity(network, limitViolation, subjectLimitViolationsBySubjectId.get(limitViolation.getSubjectId()))).collect(Collectors.toList());
}

public static PreContingencyLimitViolationEntity toEntity(LimitViolation limitViolation, SubjectLimitViolationEntity subjectLimitViolation) {
public static PreContingencyLimitViolationEntity toEntity(Network network, LimitViolation limitViolation, SubjectLimitViolationEntity subjectLimitViolation) {
return PreContingencyLimitViolationEntity.builder()
.subjectLimitViolation(subjectLimitViolation)
.limit(limitViolation.getLimit())
Expand All @@ -55,6 +53,7 @@ public static PreContingencyLimitViolationEntity toEntity(LimitViolation limitVi
.value(limitViolation.getValue())
.side(limitViolation.getSide())
.loading(computeLoading(limitViolation))
.locationId(ComputationResultUtils.getViolationLocationId(limitViolation, network))
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package org.gridsuite.securityanalysis.server.entities;

import com.powsybl.iidm.network.Network;
import com.powsybl.security.SecurityAnalysisResult;
import jakarta.persistence.*;
import lombok.*;
Expand Down Expand Up @@ -52,17 +53,17 @@ public SecurityAnalysisResultEntity(UUID id) {
this.id = id;
}

public static SecurityAnalysisResultEntity toEntity(UUID resultUuid, SecurityAnalysisResult securityAnalysisResult, SecurityAnalysisStatus securityAnalysisStatus) {
public static SecurityAnalysisResultEntity toEntity(Network network, UUID resultUuid, SecurityAnalysisResult securityAnalysisResult, SecurityAnalysisStatus securityAnalysisStatus) {
Map<String, SubjectLimitViolationEntity> subjectLimitViolationsBySubjectId = getUniqueSubjectLimitViolationsFromResult(securityAnalysisResult)
.stream().collect(Collectors.toMap(
SubjectLimitViolationEntity::getSubjectId,
subjectLimitViolation -> subjectLimitViolation)
);

List<ContingencyEntity> contingencies = securityAnalysisResult.getPostContingencyResults().stream()
.map(postContingencyResult -> ContingencyEntity.toEntity(postContingencyResult, subjectLimitViolationsBySubjectId)).collect(Collectors.toList());
.map(postContingencyResult -> ContingencyEntity.toEntity(network, postContingencyResult, subjectLimitViolationsBySubjectId)).collect(Collectors.toList());

List<PreContingencyLimitViolationEntity> preContingencyLimitViolations = PreContingencyLimitViolationEntity.toEntityList(securityAnalysisResult.getPreContingencyResult(), subjectLimitViolationsBySubjectId);
List<PreContingencyLimitViolationEntity> preContingencyLimitViolations = PreContingencyLimitViolationEntity.toEntityList(network, securityAnalysisResult.getPreContingencyResult(), subjectLimitViolationsBySubjectId);

List<SubjectLimitViolationEntity> subjectLimitViolations = Stream.concat(
contingencies.stream().flatMap(c -> c.getContingencyLimitViolations().stream()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.ThreeSides;
import com.powsybl.security.LimitViolationType;
import com.powsybl.security.SecurityAnalysisResult;
Expand Down Expand Up @@ -56,6 +57,7 @@ public class SecurityAnalysisResultService extends AbstractComputationResultServ
private static final List<String> ALLOWED_NMK_CONTINGENCIES_RESULT_SORT_PROPERTIES = List.of(
ContingencyEntity.Fields.contingencyId,
ContingencyEntity.Fields.status,
ContingencyEntity.Fields.contingencyLimitViolations + SpecificationUtils.FIELD_SEPARATOR + AbstractLimitViolationEntity.Fields.locationId,
ContingencyEntity.Fields.contingencyLimitViolations + SpecificationUtils.FIELD_SEPARATOR + AbstractLimitViolationEntity.Fields.limitType,
ContingencyEntity.Fields.contingencyLimitViolations + SpecificationUtils.FIELD_SEPARATOR + AbstractLimitViolationEntity.Fields.limitName,
ContingencyEntity.Fields.contingencyLimitViolations + SpecificationUtils.FIELD_SEPARATOR + AbstractLimitViolationEntity.Fields.limit,
Expand All @@ -68,6 +70,7 @@ public class SecurityAnalysisResultService extends AbstractComputationResultServ

private static final List<String> ALLOWED_NMK_SUBJECT_LIMIT_VIOLATIONS_RESULT_SORT_PROPERTIES = List.of(
SubjectLimitViolationEntity.Fields.subjectId,
SubjectLimitViolationEntity.Fields.contingencyLimitViolations + SpecificationUtils.FIELD_SEPARATOR + AbstractLimitViolationEntity.Fields.locationId,
SubjectLimitViolationEntity.Fields.contingencyLimitViolations + SpecificationUtils.FIELD_SEPARATOR + AbstractLimitViolationEntity.Fields.limitType,
SubjectLimitViolationEntity.Fields.contingencyLimitViolations + SpecificationUtils.FIELD_SEPARATOR + AbstractLimitViolationEntity.Fields.limitName,
SubjectLimitViolationEntity.Fields.contingencyLimitViolations + SpecificationUtils.FIELD_SEPARATOR + AbstractLimitViolationEntity.Fields.limit,
Expand All @@ -87,8 +90,9 @@ public class SecurityAnalysisResultService extends AbstractComputationResultServ
AbstractLimitViolationEntity.Fields.value,
AbstractLimitViolationEntity.Fields.loading,
AbstractLimitViolationEntity.Fields.acceptableDuration,
AbstractLimitViolationEntity.Fields.side
);
AbstractLimitViolationEntity.Fields.side,
AbstractLimitViolationEntity.Fields.locationId
);

public SecurityAnalysisResultService(SecurityAnalysisResultRepository securityAnalysisResultRepository,
ContingencyRepository contingencyRepository,
Expand Down Expand Up @@ -228,11 +232,11 @@ public void assertResultExists(UUID resultUuid) {
}

@Transactional
public void insert(UUID resultUuid, SecurityAnalysisResult result, SecurityAnalysisStatus status) {
public void insert(Network network, UUID resultUuid, SecurityAnalysisResult result, SecurityAnalysisStatus status) {
Objects.requireNonNull(resultUuid);
Objects.requireNonNull(result);

SecurityAnalysisResultEntity securityAnalysisResult = SecurityAnalysisResultEntity.toEntity(resultUuid, result, status);
SecurityAnalysisResultEntity securityAnalysisResult = SecurityAnalysisResultEntity.toEntity(network, resultUuid, result, status);
securityAnalysisResultRepository.save(securityAnalysisResult);
}

Expand Down Expand Up @@ -522,6 +526,8 @@ private static Comparator<ContingencyLimitViolationEntity> getCommonComparator(S
Comparator.comparing(AbstractLimitViolationEntity::getSide, Comparator.nullsLast(Comparator.naturalOrder()));
case AbstractLimitViolationEntity.Fields.loading ->
Comparator.comparing(AbstractLimitViolationEntity::getLoading, Comparator.nullsLast(Comparator.naturalOrder()));
case AbstractLimitViolationEntity.Fields.locationId ->
Comparator.comparing(AbstractLimitViolationEntity::getLocationId, Comparator.nullsLast(Comparator.naturalOrder()));
default -> throw new IllegalArgumentException("Sorting on the column '" + field + "' is not supported"); // not supposed to happen
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ protected void postRun(SecurityAnalysisRunContext runContext, AtomicReference<Re

@Override
protected void saveResult(Network network, AbstractResultContext<SecurityAnalysisRunContext> resultContext, SecurityAnalysisResult result) {
resultService.insert(
resultService.insert(network,
resultContext.getResultUuid(),
result,
result.getPreContingencyResult().getStatus() == LoadFlowResult.ComponentResult.Status.CONVERGED
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:pro="http://www.liquibase.org/xml/ns/pro" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet author="ajellalali (generated)" id="1738944714380-1">
<addColumn tableName="contingency_limit_violation">
<column name="location_id" type="varchar(255)"/>
</addColumn>
</changeSet>
<changeSet author="ajellalali (generated)" id="1738944714380-2">
<addColumn tableName="pre_contingency_limit_violation">
<column name="location_id" type="varchar(255)"/>
</addColumn>
</changeSet>
</databaseChangeLog>
4 changes: 3 additions & 1 deletion src/main/resources/db/changelog/db.changelog-master.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,6 @@ databaseChangeLog:
- include:
file: changesets/changelog_20241212T111835Z.xml
relativeToChangelogFile: true

- include:
file: changesets/changelog_20250207T161145Z.xml
relativeToChangelogFile: true
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
*/
package org.gridsuite.securityanalysis.server;

import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.ThreeSides;
import com.powsybl.iidm.network.VariantManagerConstants;
import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory;
import com.powsybl.network.store.iidm.impl.NetworkFactoryImpl;
import com.powsybl.security.LimitViolationType;
import org.gridsuite.securityanalysis.server.dto.ContingencyResultDTO;
import org.gridsuite.securityanalysis.server.dto.ResourceFilterDTO;
Expand Down Expand Up @@ -61,7 +65,12 @@ class FindContingenciesTest {

@BeforeAll
void setUp() {
resultEntity = SecurityAnalysisResultEntity.toEntity(UUID.randomUUID(), RESULT, SecurityAnalysisStatus.CONVERGED);
// network store service mocking
Network network = EurostagTutorialExample1Factory.create(new NetworkFactoryImpl());
network.getVariantManager().cloneVariant(VariantManagerConstants.INITIAL_VARIANT_ID, VARIANT_1_ID);
network.getVariantManager().cloneVariant(VariantManagerConstants.INITIAL_VARIANT_ID, VARIANT_2_ID);
network.getVariantManager().cloneVariant(VariantManagerConstants.INITIAL_VARIANT_ID, VARIANT_3_ID);
resultEntity = SecurityAnalysisResultEntity.toEntity(network, UUID.randomUUID(), RESULT, SecurityAnalysisStatus.CONVERGED);
securityAnalysisResultRepository.save(resultEntity);
}

Expand Down
Loading