Skip to content

Commit

Permalink
Refacto voltage init endpoints to take into account root networks
Browse files Browse the repository at this point in the history
Signed-off-by: Slimane AMAR <[email protected]>
  • Loading branch information
Slimane AMAR committed Jan 23, 2025
1 parent a5386c1 commit c399b15
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public ResponseEntity<List<Optional<NetworkModificationResult>>> handleNetworkMo
@RequestBody Pair<List<UUID>, List<ModificationApplicationContext>> modificationContextInfos) {
return switch (action) {
case COPY ->
ResponseEntity.ok().body(networkModificationService.duplicateModifications(targetGroupUuid, modificationContextInfos.getFirst(), modificationContextInfos.getSecond()));
ResponseEntity.ok().body(networkModificationService.duplicateModifications(targetGroupUuid, originGroupUuid, modificationContextInfos.getFirst(), modificationContextInfos.getSecond()));
case INSERT ->
ResponseEntity.ok().body(networkModificationService.insertCompositeModifications(targetGroupUuid, modificationContextInfos.getFirst(), modificationContextInfos.getSecond()));
case MOVE -> {
Expand Down Expand Up @@ -254,13 +254,6 @@ public ResponseEntity<Void> deleteLineTypesCatalog() {
return ResponseEntity.ok().build();
}

@PostMapping(value = "/groups/modification", consumes = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Create a group containing a modification")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The group with the modification has been created")})
public ResponseEntity<UUID> createModificationInGroup(@RequestBody ModificationInfos modificationsInfos) {
return ResponseEntity.ok().body(networkModificationService.createModificationInGroup(modificationsInfos));
}

@PostMapping(value = "/network-composite-modifications", consumes = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Create a network composite modification")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The composite modification has been created")})
Expand Down Expand Up @@ -313,18 +306,6 @@ public ResponseEntity<Void> updateNetworkModificationsActivationStatus(
return ResponseEntity.ok().build();
}

@PutMapping(value = "/groups/{groupUuid}/duplications", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Duplicate all modifications in a group and append them at the end of another modifications group")
@ApiResponse(responseCode = "200", description = "The modifications have been duplicated")
public ResponseEntity<Optional<NetworkModificationResult>> duplicateModificationsInGroup(@Parameter(description = "updated group UUID, where modifications are pasted") @PathVariable("groupUuid") UUID targetGroupUuid,
@Parameter(description = "the network uuid", required = true) @RequestParam(value = "networkUuid") UUID networkUuid,
@Parameter(description = "the report uuid", required = true) @RequestParam(value = "reportUuid") UUID reportUuid,
@Parameter(description = "the reporter id", required = true) @RequestParam(value = "reporterId") UUID reporterId,
@Parameter(description = "the variant id", required = true) @RequestParam(value = "variantId") String variantId,
@Parameter(description = "origin group UUID, from where modifications are copied") @RequestParam(value = "duplicateFrom") UUID originGroupUuid) {
return ResponseEntity.ok().body(networkModificationService.duplicateModificationsInGroup(targetGroupUuid, networkUuid, variantId, new ReportInfos(reportUuid, reporterId), originGroupUuid));
}

@DeleteMapping(value = "/groups/{groupUuid}/stashed-modifications")
@Operation(summary = "Delete the stashed modifications in a group")
@ApiResponse(responseCode = "200", description = "Stashed modifications in the group deleted")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
Copyright (c) 2025, 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.modification.server;

import com.powsybl.commons.PowsyblException;
import lombok.Getter;
import org.springframework.http.HttpStatus;

import java.util.Objects;

/**
* @author Slimane Amar <slimane.amar at rte-france.com>
*/
public class NetworkModificationServerException extends PowsyblException {
public enum Type {
DUPLICATION_ARGUMENT_INVALID(HttpStatus.BAD_REQUEST, "Invalid argument for duplication");

public final HttpStatus status;
private final String message;

Type(HttpStatus status, String message) {
this.status = status;
this.message = message;
}
}

@Getter
private final Type type;

public NetworkModificationServerException(Type type) {
super(Objects.requireNonNull(type.name()) + ((type.message == null) ? "" : " : " + type.message));
this.type = type;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.gridsuite.modification.NetworkModificationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
Expand All @@ -20,14 +21,24 @@
public class RestResponseEntityExceptionHandler {

private static final Logger LOGGER = LoggerFactory.getLogger(RestResponseEntityExceptionHandler.class);
private static final String HANDLER_MESSAGE = "Caught in handler";

@ExceptionHandler(NetworkModificationException.class)
protected ResponseEntity<Object> handleNetworkModificationException(NetworkModificationException exception) {
protected ResponseEntity<Object> handleException(NetworkModificationException exception) {
return handleException(exception.getType().status, exception);
}

@ExceptionHandler(NetworkModificationServerException.class)
protected ResponseEntity<Object> handleException(NetworkModificationServerException exception) {
return handleException(exception.getType().status, exception);
}

private ResponseEntity<Object> handleException(HttpStatus status, Exception exception) {
if (LOGGER.isErrorEnabled()) {
LOGGER.error(exception.getMessage());
LOGGER.error(HANDLER_MESSAGE, exception);
}
return ResponseEntity
.status(exception.getType().status)
.body(exception.getMessage());
.status(status)
.body(exception.getMessage());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.gridsuite.modification.dto.ModificationInfos;
import org.gridsuite.modification.ModificationType;
import org.gridsuite.modification.NetworkModificationException;
import org.gridsuite.modification.server.NetworkModificationServerException;
import org.gridsuite.modification.server.dto.*;
import org.gridsuite.modification.server.elasticsearch.EquipmentInfosService;
import org.gridsuite.modification.server.entities.ModificationEntity;
Expand All @@ -31,6 +32,7 @@
import java.util.stream.Collectors;

import static org.gridsuite.modification.NetworkModificationException.Type.*;
import static org.gridsuite.modification.server.NetworkModificationServerException.Type.DUPLICATION_ARGUMENT_INVALID;

/**
* @author Franck Lecuyer <franck.lecuyer at rte-france.com>
Expand Down Expand Up @@ -325,8 +327,11 @@ private Optional<NetworkModificationResult> applyModifications(UUID networkUuid,
}

@Transactional
public List<Optional<NetworkModificationResult>> duplicateModifications(@NonNull UUID targetGroupUuid, @NonNull List<UUID> modificationsUuids, @NonNull List<ModificationApplicationContext> applicationContexts) {
List<ModificationInfos> modificationInfos = networkModificationRepository.getModificationsInfos(modificationsUuids);
public List<Optional<NetworkModificationResult>> duplicateModifications(@NonNull UUID targetGroupUuid, UUID originGroupUuid, @NonNull List<UUID> modificationsUuids, @NonNull List<ModificationApplicationContext> applicationContexts) {
if (originGroupUuid != null && !modificationsUuids.isEmpty()) { // Duplicate modifications from a group or from a list only
throw new NetworkModificationServerException(DUPLICATION_ARGUMENT_INVALID);
}
List<ModificationInfos> modificationInfos = originGroupUuid != null ? networkModificationRepository.getActiveModificationsInfos(originGroupUuid) : networkModificationRepository.getModificationsInfos(modificationsUuids);
networkModificationRepository.saveModificationInfos(targetGroupUuid, modificationInfos);
return applyModifications(modificationInfos, applicationContexts);
}
Expand Down Expand Up @@ -364,12 +369,6 @@ public Optional<NetworkModificationResult> insertCompositeModifications(UUID tar
return applyModifications(networkUuid, variantId, reportInfos, modificationInfos);
}

public UUID createModificationInGroup(@NonNull ModificationInfos modificationsInfos) {
UUID groupUuid = UUID.randomUUID();
networkModificationRepository.saveModificationInfos(groupUuid, List.of(modificationsInfos));
return groupUuid;
}

@Transactional
public UUID createNetworkCompositeModification(@NonNull List<UUID> modificationUuids) {
return networkModificationRepository.createNetworkCompositeModification(modificationUuids);
Expand All @@ -379,16 +378,6 @@ public Map<UUID, UUID> duplicateModifications(List<UUID> sourceModificationUuids
return networkModificationRepository.duplicateModifications(sourceModificationUuids);
}

@Transactional
public Optional<NetworkModificationResult> duplicateModificationsInGroup(UUID targetGroupUuid,
UUID networkUuid, String variantId,
ReportInfos reportInfos,
UUID originGroupUuid) {
List<ModificationInfos> modificationsInfos = networkModificationRepository.getActiveModificationsInfos(originGroupUuid);
networkModificationRepository.saveModificationInfos(targetGroupUuid, modificationsInfos);
return applyModifications(networkUuid, variantId, reportInfos, modificationsInfos);
}

public void deleteStashedModificationInGroup(UUID groupUuid, boolean errorOnGroupNotFound) {
networkModificationRepository.deleteStashedModificationInGroup(groupUuid, errorOnGroupNotFound);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@

import static org.gridsuite.modification.ModificationType.EQUIPMENT_ATTRIBUTE_MODIFICATION;
import static org.gridsuite.modification.NetworkModificationException.Type.*;
import static org.gridsuite.modification.server.NetworkModificationServerException.Type.DUPLICATION_ARGUMENT_INVALID;
import static org.gridsuite.modification.server.impacts.TestImpactUtils.*;
import static org.gridsuite.modification.server.utils.TestUtils.assertLogMessage;
import static org.gridsuite.modification.server.utils.assertions.Assertions.assertThat;
Expand Down Expand Up @@ -577,16 +578,14 @@ void testCopyModification() throws Exception {
assertThat(newModificationListOtherGroup.get(2)).recursivelyEquals(modificationList.get(1));

// Duplicate all modifications in TEST_GROUP_ID, and append them at the end of otherGroupId
applicationContext = new ModificationApplicationContext(TEST_NETWORK_ID, NetworkCreation.VARIANT_ID, TEST_REPORT_ID, UUID.randomUUID());
bodyJson = objectWriter.writeValueAsString(org.springframework.data.util.Pair.of(List.of(), List.of(applicationContext)));
mvcResult = mockMvc.perform(
put("/v1/groups/" + otherGroupId + "/duplications"
+ "?networkUuid=" + TEST_NETWORK_ID
+ "&reportUuid=" + TEST_REPORT_ID
+ "&reporterId=" + UUID.randomUUID()
+ "&variantId=" + NetworkCreation.VARIANT_ID
+ "&duplicateFrom=" + TEST_GROUP_ID)
put("/v1/groups/" + otherGroupId + "?action=COPY" + "&originGroupUuid=" + TEST_GROUP_ID)
.content(bodyJson)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk()).andReturn();
assertApplicationStatusOK(mvcResult);
assertApplicationStatusOKNew(mvcResult);

newModificationListOtherGroup = modificationRepository.getModifications(otherGroupId, true, true);
// now 8 modifications in new group: first 3 are still the same, 5 last are new duplicates from first group
Expand All @@ -597,6 +596,16 @@ void testCopyModification() throws Exception {
for (int i = 3; i < 8; ++i) {
assertThat(newModificationListOtherGroup.get(i)).recursivelyEquals(modificationList.get(i - 3));
}

// Duplicate modifications from a group and from a list : illegal operation
applicationContext = new ModificationApplicationContext(TEST_NETWORK_ID, NetworkCreation.VARIANT_ID, TEST_REPORT_ID, UUID.randomUUID());
bodyJson = objectWriter.writeValueAsString(org.springframework.data.util.Pair.of(duplicateModificationUuidList, List.of(applicationContext)));
mvcResult = mockMvc.perform(
put("/v1/groups/" + otherGroupId + "?action=COPY" + "&originGroupUuid=" + TEST_GROUP_ID)
.content(bodyJson)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isBadRequest()).andReturn();
assertEquals(new NetworkModificationServerException(DUPLICATION_ARGUMENT_INVALID).getMessage(), mvcResult.getResponse().getContentAsString());
}

/**
Expand Down Expand Up @@ -671,16 +680,14 @@ void testCopyModificationOld() throws Exception {
assertThat(newModificationListOtherGroup.get(2)).recursivelyEquals(modificationList.get(1));

// Duplicate all modifications in TEST_GROUP_ID, and append them at the end of otherGroupId
ModificationApplicationContext applicationContext = new ModificationApplicationContext(TEST_NETWORK_ID, NetworkCreation.VARIANT_ID, TEST_REPORT_ID, UUID.randomUUID());
String bodyJson = objectWriter.writeValueAsString(org.springframework.data.util.Pair.of(List.of(), List.of(applicationContext)));
mvcResult = mockMvc.perform(
put("/v1/groups/" + otherGroupId + "/duplications"
+ "?networkUuid=" + TEST_NETWORK_ID
+ "&reportUuid=" + TEST_REPORT_ID
+ "&reporterId=" + UUID.randomUUID()
+ "&variantId=" + NetworkCreation.VARIANT_ID
+ "&duplicateFrom=" + TEST_GROUP_ID)
put("/v1/groups/" + otherGroupId + "?action=COPY" + "&originGroupUuid=" + TEST_GROUP_ID)
.content(bodyJson)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk()).andReturn();
assertApplicationStatusOK(mvcResult);
assertApplicationStatusOKNew(mvcResult);

newModificationListOtherGroup = modificationRepository.getModifications(otherGroupId, true, true);
// now 8 modifications in new group: first 3 are still the same, 5 last are new duplicates from first group
Expand Down Expand Up @@ -1633,15 +1640,15 @@ void testCreateVoltageInitModification() throws Exception {
.build()))
.build();

MvcResult mvcResult = mockMvc.perform(post("/v1/groups/modification")
.content(objectWriter.writeValueAsString(modificationsInfos1))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andReturn();
UUID groupUuid = UUID.fromString(mapper.readValue(mvcResult.getResponse().getContentAsString(), String.class));
UUID groupUuid = UUID.randomUUID();
mockMvc.perform(post(URI_NETWORK_MODIF_BASE)
.queryParam("groupUuid", groupUuid.toString())
.content(objectWriter.writeValueAsString(org.springframework.data.util.Pair.of(modificationsInfos1, List.of())))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());

// Get the modifications
mvcResult = mockMvc.perform(get("/v1/groups/{groupUuid}/network-modifications?onlyMetadata=false", groupUuid)).andExpectAll(
MvcResult mvcResult = mockMvc.perform(get("/v1/groups/{groupUuid}/network-modifications?onlyMetadata=false", groupUuid)).andExpectAll(
status().isOk(), content().contentType(MediaType.APPLICATION_JSON))
.andReturn();

Expand Down Expand Up @@ -1786,14 +1793,15 @@ void testApplyModificationsFromUuids() throws Exception {
CompositeModificationInfos compositeModificationInfos = CompositeModificationInfos.builder()
.modifications(List.of(switchStatusModificationInfos))
.build();
MvcResult mvcResult = mockMvc.perform(post("/v1/groups/modification")
.content(objectWriter.writeValueAsString(compositeModificationInfos))

UUID groupUuid = UUID.randomUUID();
mockMvc.perform(post(URI_NETWORK_MODIF_BASE)
.queryParam("groupUuid", groupUuid.toString())
.content(objectWriter.writeValueAsString(org.springframework.data.util.Pair.of(compositeModificationInfos, List.of())))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andReturn();
UUID groupUuid = UUID.fromString(mapper.readValue(mvcResult.getResponse().getContentAsString(), String.class));
.andExpect(status().isOk());

mvcResult = mockMvc.perform(get("/v1/groups/{groupUuid}/network-modifications?onlyMetadata=false", groupUuid)).andExpectAll(
MvcResult mvcResult = mockMvc.perform(get("/v1/groups/{groupUuid}/network-modifications?onlyMetadata=false", groupUuid)).andExpectAll(
status().isOk(), content().contentType(MediaType.APPLICATION_JSON))
.andReturn();
List<ModificationInfos> modificationsInfos = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ void testVoltageInitDuplicationLogs(final ApplicationStatus resultStatus, final

final UUID networkUuuid = UUID.fromString("11111111-1111-1111-1111-111111111111");
final UUID reportUuid = UUID.fromString("88888888-8888-8888-8888-888888888888");
//simulate PUT /v1/groups/abc/duplications?networkUuid=0000&reportUuid=0000&reporterId=0000&variantId=0000&duplicateFrom=0000
//simulate PUT /v1/groups/abc?action=COPY with body ModificationApplicationContext(networkUuid=0000, reportUuid=0000, reporterId=0000, variantId=0000, duplicateFrom=0000)
assertThat(networkModificationApplicator.applyModifications(
List.of(modificationInfos),
new NetworkInfos(network, networkUuuid, true),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ void testSqlRequestsCountOnPostGroups2() throws Exception {
}

/*
PUT /v1/groups/{groupUuid}/duplications SQL requests analysis
PUT /v1/groups/{groupUuid}?action=COPY SQL requests analysis
Given an example with 2 tabular modifications having 1000 modifications each
Expand Down
Loading

0 comments on commit c399b15

Please sign in to comment.