Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add location id to the SA result #158

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
<liquibase-hibernate-package>org.gridsuite.securityanalysis.server</liquibase-hibernate-package>
<db-util.version>1.0.5</db-util.version>
<mockwebserver3.version>5.0.0-alpha.14</mockwebserver3.version>
<!-- FIXME: powsybl-ws-commons modules'version is overloaded in the dependencies section
The overloads and this property below have to be removed at next powsybl-ws-dependencies.version upgrade -->
<powsybl-ws-commons.version>1.17.0</powsybl-ws-commons.version>
</properties>

<build>
Expand Down Expand Up @@ -144,6 +147,8 @@
<dependency>
<groupId>com.powsybl</groupId>
<artifactId>powsybl-ws-commons</artifactId>
<version>${powsybl-ws-commons.version}</version>

</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,20 @@
public class PreContingencyLimitViolationResultDTO {

private String subjectId;
private String locationId;
private String status;
private LimitViolationDTO limitViolation;

public static PreContingencyLimitViolationResultDTO toDto(PreContingencyLimitViolationEntity preContingencyLimitViolation) {
String subjectId = preContingencyLimitViolation.getSubjectLimitViolation() != null
? preContingencyLimitViolation.getSubjectLimitViolation().getSubjectId()
: null;

String locationId = preContingencyLimitViolation.getSubjectLimitViolation() != null
? preContingencyLimitViolation.getSubjectLimitViolation().getLocationId()
: null;
return PreContingencyLimitViolationResultDTO.builder()
.subjectId(subjectId)
.locationId(locationId)
.status(preContingencyLimitViolation.getResult().getPreContingencyStatus())
.limitViolation(LimitViolationDTO.toDto(preContingencyLimitViolation))
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
@Builder
public class SubjectLimitViolationDTO {
private String subjectId;
private String locationId;

private LimitViolationDTO limitViolation;

Expand All @@ -29,8 +30,13 @@ public static SubjectLimitViolationDTO toDto(ContingencyLimitViolationEntity lim
? limitViolation.getSubjectLimitViolation().getSubjectId()
: null;

String locationId = limitViolation.getSubjectLimitViolation() != null
? limitViolation.getSubjectLimitViolation().getLocationId()
: null;

return SubjectLimitViolationDTO.builder()
.subjectId(subjectId)
.locationId(locationId)
.limitViolation(LimitViolationDTO.toDto(limitViolation))
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
public class SubjectLimitViolationResultDTO {
private String subjectId;

private String locationId;

private List<ContingencyLimitViolationDTO> contingencies;

public static SubjectLimitViolationResultDTO toDto(SubjectLimitViolationEntity subjectLimitViolation) {
Expand All @@ -37,6 +39,7 @@ public static SubjectLimitViolationResultDTO toDto(SubjectLimitViolationEntity s

return SubjectLimitViolationResultDTO.builder()
.subjectId(subjectLimitViolation.getSubjectId())
.locationId(subjectLimitViolation.getLocationId())
.contingencies(contingencies)
.build();
}
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 @@ -64,11 +65,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,8 @@ 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) {
subjectLimitViolation.setLocationId(ComputationResultUtils.getViolationLocationId(limitViolation, network));
ContingencyLimitViolationEntity contingencyLimitViolationEntity = ContingencyLimitViolationEntity.builder()
.limit(limitViolation.getLimit())
.limitName(limitViolation.getLimitName())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
*/
package org.gridsuite.securityanalysis.server.entities;

import com.powsybl.iidm.network.Network;
import com.powsybl.security.LimitViolation;
import com.powsybl.security.results.PreContingencyResult;
import com.powsybl.ws.commons.computation.utils.ComputationResultUtils;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.ManyToOne;
Expand Down Expand Up @@ -40,11 +42,12 @@ public class PreContingencyLimitViolationEntity extends AbstractLimitViolationEn
@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) {
subjectLimitViolation.setLocationId(ComputationResultUtils.getViolationLocationId(limitViolation, network));
return PreContingencyLimitViolationEntity.builder()
.subjectLimitViolation(subjectLimitViolation)
.limit(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.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 @@ -39,6 +39,11 @@ public SubjectLimitViolationEntity(String subjectId, String subjectName) {

private String subjectName;

@Column
@Setter
@Getter
private String locationId;

@ManyToOne(fetch = FetchType.LAZY)
@Setter
@Getter
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 @@ -228,11 +229,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
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,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
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_20241223T154019Z.xml
relativeToChangelogFile: true
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,18 @@
*/
package org.gridsuite.securityanalysis.server;

import com.github.tomakehurst.wiremock.WireMockServer;
import com.powsybl.commons.report.ReportNode;
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.client.NetworkStoreService;
import com.powsybl.network.store.client.PreloadingStrategy;
import com.powsybl.network.store.iidm.impl.NetworkFactoryImpl;
import com.powsybl.security.LimitViolationType;
import com.powsybl.ws.commons.computation.service.ReportService;
import com.powsybl.ws.commons.computation.service.UuidGeneratorService;
import org.gridsuite.securityanalysis.server.dto.ContingencyResultDTO;
import org.gridsuite.securityanalysis.server.dto.ResourceFilterDTO;
import org.gridsuite.securityanalysis.server.dto.SecurityAnalysisStatus;
Expand All @@ -26,8 +36,10 @@
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
Expand All @@ -38,19 +50,27 @@
import java.util.UUID;
import java.util.stream.Stream;

import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import static com.vladmihalcea.sql.SQLStatementCountValidator.assertSelectCount;
import static com.vladmihalcea.sql.SQLStatementCountValidator.reset;
import static org.assertj.core.api.Assertions.assertThat;
import static org.gridsuite.securityanalysis.server.SecurityAnalysisProviderMock.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.doNothing;

/**
* @author Kevin Le Saulnier <kevin.lesaulnier at rte-france.com>
*/
@SpringBootTest // would be better with @DataJpaTest but does not work here
@TestInstance(TestInstance.Lifecycle.PER_CLASS) // improve tests speed as we only read DB
class FindContingenciesTest {

private static final UUID NETWORK_UUID = UUID.fromString("7928181c-7977-4592-ba19-88027e4254e4");
private static final UUID RESULT_UUID = UUID.fromString("0c8de370-3e6c-4d72-b292-d355a97e0d5d");

@Autowired
private SecurityAnalysisResultRepository securityAnalysisResultRepository;

Expand All @@ -59,9 +79,34 @@ class FindContingenciesTest {
@Autowired
private SecurityAnalysisResultService securityAnalysisResultService;

@MockBean
private NetworkStoreService networkStoreService;
@MockBean
private UuidGeneratorService uuidGeneratorService;

@MockBean
private ReportService reportService;

@BeforeAll
void setUp() {
resultEntity = SecurityAnalysisResultEntity.toEntity(UUID.randomUUID(), RESULT, SecurityAnalysisStatus.CONVERGED);
WireMockServer wireMockServer = new WireMockServer(wireMockConfig().dynamicPort());
wireMockServer.start();
MockitoAnnotations.initMocks(this);

// 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);

given(networkStoreService.getNetwork(NETWORK_UUID, PreloadingStrategy.ALL_COLLECTIONS_NEEDED_FOR_BUS_VIEW)).willReturn(network);

// UUID service mocking to always generate the same result UUID
given(uuidGeneratorService.generate()).willReturn(RESULT_UUID);

doNothing().when(reportService).sendReport(any(UUID.class), any(ReportNode.class));

resultEntity = SecurityAnalysisResultEntity.toEntity(network, UUID.randomUUID(), RESULT, SecurityAnalysisStatus.CONVERGED);
securityAnalysisResultRepository.save(resultEntity);
}

Expand Down
Loading
Loading