Skip to content

Commit

Permalink
Creating modifications should now impact ES index (#365)
Browse files Browse the repository at this point in the history
Signed-off-by: LE SAULNIER Kevin <[email protected]>
  • Loading branch information
klesaulnier authored Dec 1, 2023
1 parent 0777d9c commit b890363
Show file tree
Hide file tree
Showing 6 changed files with 282 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,15 @@
*/
package org.gridsuite.modification.server.dto;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.*;
import lombok.experimental.SuperBuilder;

/**
* @author Achour Berrahma <achour.berrahma at rte-france.com>
*/
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@Getter
@ToString
@EqualsAndHashCode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,15 @@
*/
package org.gridsuite.modification.server.dto;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.*;
import lombok.experimental.SuperBuilder;

/**
* @author Nicolas Noir <nicolas.noir at rte-france.com>
*/
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@Getter
@ToString
@EqualsAndHashCode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,5 +101,4 @@ public static Set<SubstationInfos> getSubstationsInfos(@NonNull Identifiable<?>
.name(vl.getSubstation().map(Substation::getNameOrId).orElse(null)).build())
.collect(Collectors.toSet());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package org.gridsuite.modification.server.modifications;

import com.google.common.collect.Iterables;
import com.powsybl.iidm.network.*;
import com.powsybl.network.store.client.NetworkStoreService;
import lombok.Setter;
Expand Down Expand Up @@ -40,6 +41,8 @@ public class NetworkStoreListener implements NetworkListener {

private final List<EquipmentInfos> createdEquipments = new ArrayList<>();

private final List<EquipmentInfos> modifiedEquipments = new ArrayList<>();

private final Set<SimpleElementImpact> networkImpacts = new LinkedHashSet<>();

// TODO : Move to the NetworkModificationApplicator class
Expand Down Expand Up @@ -92,18 +95,6 @@ public Network getNetwork() {
return network;
}

@Override
public void onUpdate(Identifiable identifiable, String attribute, Object oldValue, Object newValue) {
networkImpacts.add(
SimpleElementImpact.builder()
.impactType(SimpleElementImpact.SimpleImpactType.MODIFICATION)
.elementType(identifiable.getType())
.elementId(identifiable.getId())
.substationIds(getSubstationIds(identifiable))
.build()
);
}

private void addSimpleModificationImpact(Identifiable<?> identifiable) {
networkImpacts.add(
SimpleElementImpact.builder()
Expand All @@ -130,9 +121,66 @@ public void onElementReplaced(Identifiable identifiable, String attribute, Objec
addSimpleModificationImpact(identifiable);
}

@Override
public void onUpdate(Identifiable identifiable, String attribute, Object oldValue, Object newValue) {
addSimpleModificationImpact(identifiable);
updateEquipmentIndexation(identifiable, attribute, networkUuid, network.getVariantManager().getWorkingVariantId());
}

@Override
public void onUpdate(Identifiable identifiable, String attribute, String variantId, Object oldValue, Object newValue) {
addSimpleModificationImpact(identifiable);
updateEquipmentIndexation(identifiable, attribute, networkUuid, network.getVariantManager().getWorkingVariantId());
}

private void updateEquipmentIndexation(Identifiable<?> identifiable, String attribute, UUID networkUuid, String variantId) {
modifiedEquipments.add(toEquipmentInfos(identifiable, networkUuid, variantId));

// because all each equipment carry its linked voltage levels/substations name within its document
// if attribute is "name" and identifiable type is VOLTAGE_LEVEL or SUBSTATION, we need to update all equipments linked to it
if (attribute.equals("name") && (identifiable.getType().equals(IdentifiableType.VOLTAGE_LEVEL) || identifiable.getType().equals(IdentifiableType.SUBSTATION))) {
updateLinkedEquipments(identifiable);
}
}

private void updateLinkedEquipments(Identifiable<?> identifiable) {
if (identifiable.getType().equals(IdentifiableType.VOLTAGE_LEVEL)) {
VoltageLevel updatedVoltageLevel = network.getVoltageLevel(identifiable.getId());
// update all equipments linked to voltageLevel
updateEquipmentsLinkedToVoltageLevel(updatedVoltageLevel);
// update substation linked to voltageLevel
Optional<Substation> linkedSubstation = updatedVoltageLevel.getSubstation();
if (linkedSubstation.isPresent()) {
modifiedEquipments.add(toEquipmentInfos(linkedSubstation.get(), networkUuid, network.getVariantManager().getWorkingVariantId()));
}
} else if (identifiable.getType().equals(IdentifiableType.SUBSTATION)) {
Substation updatedSubstation = network.getSubstation(identifiable.getId());
updateEquipmentsLinkedToSubstation(updatedSubstation);
}
}

private void updateEquipmentsLinkedToSubstation(Substation substation) {
Iterable<VoltageLevel> linkedVoltageLevels = substation.getVoltageLevels();
// update all voltageLevels linked to substation
linkedVoltageLevels.forEach(vl -> modifiedEquipments.add(toEquipmentInfos(vl, networkUuid, network.getVariantManager().getWorkingVariantId())));
// update all equipments linked to each of the voltageLevels
linkedVoltageLevels.forEach(vl ->
Iterables.concat(
vl.getConnectables(),
vl.getSwitches()
).forEach(c ->
modifiedEquipments.add(toEquipmentInfos(c, networkUuid, network.getVariantManager().getWorkingVariantId()))
)
);
}

private void updateEquipmentsLinkedToVoltageLevel(VoltageLevel voltageLevel) {
Iterables.concat(
voltageLevel.getConnectables(),
voltageLevel.getSwitches()
).forEach(c ->
modifiedEquipments.add(toEquipmentInfos(c, networkUuid, network.getVariantManager().getWorkingVariantId()))
);
}

@Override
Expand Down Expand Up @@ -192,6 +240,18 @@ public NetworkModificationResult flushNetworkModifications() {
.build();
}

private static EquipmentInfos toEquipmentInfos(Identifiable<?> identifiable, UUID networkUuid, String variantId) {
return EquipmentInfos.builder()
.networkUuid(networkUuid)
.variantId(variantId)
.id(identifiable.getId())
.name(identifiable.getNameOrId())
.type(identifiable.getType().name())
.voltageLevels(EquipmentInfos.getVoltageLevelsInfos(identifiable))
.substations(EquipmentInfos.getSubstationsInfos(identifiable))
.build();
}

private void flushEquipmentInfos() {
String variantId = network.getVariantManager().getWorkingVariantId();
Set<String> presentEquipmentDeletionsIds = equipmentInfosService.findEquipmentInfosList(deletedEquipmentsIds, networkUuid, variantId).stream().map(EquipmentInfos::getId).collect(Collectors.toSet());
Expand All @@ -213,5 +273,6 @@ private void flushEquipmentInfos() {
equipmentInfosService.deleteEquipmentInfosList(equipmentDeletionsIds, networkUuid, variantId);
equipmentInfosService.addAllTombstonedEquipmentInfos(tombstonedEquipmentInfos);
equipmentInfosService.addAllEquipmentInfos(createdEquipments);
equipmentInfosService.addAllEquipmentInfos(modifiedEquipments);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package org.gridsuite.modification.server.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.powsybl.iidm.network.LoadType;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.VariantManagerConstants;
import com.powsybl.network.store.client.NetworkStoreService;
import com.powsybl.network.store.client.PreloadingStrategy;
import org.gridsuite.modification.server.dto.LoadCreationInfos;
import org.gridsuite.modification.server.dto.LoadModificationInfos;
import org.gridsuite.modification.server.dto.VoltageLevelModificationInfos;
import org.gridsuite.modification.server.elasticsearch.EquipmentInfosRepository;
import org.gridsuite.modification.server.elasticsearch.EquipmentInfosService;
import org.gridsuite.modification.server.repositories.ModificationRepository;
import org.gridsuite.modification.server.utils.ModificationCreation;
import org.gridsuite.modification.server.utils.NetworkCreation;
import org.junit.Before;
import org.junit.jupiter.api.Tag;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.stubbing.Answer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

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

import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
@SpringBootTest
@Tag("IntegrationTest")
public class ModificationElasticsearchTest {
private static UUID NETWORK_UUID = UUID.randomUUID();
private static final UUID TEST_GROUP_ID = UUID.randomUUID();
private static final UUID TEST_REPORT_ID = UUID.randomUUID();
private static final String URI_NETWORK_MODIF_BASE = "/v1/network-modifications";
private static final String URI_NETWORK_MODIF_PARAMS = "&groupUuid=" + TEST_GROUP_ID + "&reportUuid=" + TEST_REPORT_ID + "&reporterId=" + UUID.randomUUID();
private static final String URI_NETWORK_MODIF = URI_NETWORK_MODIF_BASE + "?networkUuid=" + NETWORK_UUID + URI_NETWORK_MODIF_PARAMS;

private static final String NEW_VARIANT = "NewVariant";
private static final String NEW_VARIANT_2 = "NewVariant2";

@Autowired
MockMvc mockMvc;

@Autowired
private ObjectMapper mapper;

@Autowired
EquipmentInfosService equipmentInfosService;

@Autowired
ModificationRepository modificationRepository;

@MockBean
NetworkStoreService networkStoreService;

@MockBean
ReportService reportService;

@Autowired
private EquipmentInfosRepository equipmentInfosRepository;

Network network;

@Before
public void setUp() {
network = NetworkCreation.create(NETWORK_UUID, true);
when(networkStoreService.getNetwork(eq(NETWORK_UUID), nullable(PreloadingStrategy.class))).then((Answer<Network>) invocation -> network);

// clean DB
modificationRepository.deleteAll();
equipmentInfosService.deleteAll();
}

@Test
public void testModificationsToImpactElasticsearch() throws Exception {
network.getVariantManager().cloneVariant(VariantManagerConstants.INITIAL_VARIANT_ID, NEW_VARIANT);
network.getVariantManager().setWorkingVariant(NEW_VARIANT);

// load creation - assert name and vl name values
LoadCreationInfos loadCreationInfos = ModificationCreation.getCreationLoad("v1", "v1Load", "v1load_name", "1.1", LoadType.UNDEFINED);
String loadCreationJson = mapper.writeValueAsString(loadCreationInfos);
mockMvc.perform(post(URI_NETWORK_MODIF).content(loadCreationJson).contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andReturn();
assertEquals("v1load_name", equipmentInfosRepository.findByIdInAndNetworkUuidAndVariantId(List.of("v1Load"), NETWORK_UUID, NEW_VARIANT).get(0).getName());
assertTrue(equipmentInfosRepository.findByIdInAndNetworkUuidAndVariantId(List.of("v1Load"), NETWORK_UUID, NEW_VARIANT).get(0).getVoltageLevels().stream().anyMatch(vl -> vl.getName().equals("v1")));

// load modification - assert name modification
LoadModificationInfos loadModification = ModificationCreation.getModificationLoad("v1Load", null, "v1load_newname", null, null, null, null);
String loadModificationJson = mapper.writeValueAsString(loadModification);
mockMvc.perform(post(URI_NETWORK_MODIF).content(loadModificationJson).contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andReturn();
assertEquals("v1load_newname", equipmentInfosRepository.findByIdInAndNetworkUuidAndVariantId(List.of("v1Load"), NETWORK_UUID, NEW_VARIANT).get(0).getName());
}

@Test
public void testVLModificationsToImpactElasticsearch() throws Exception {
network.getVariantManager().cloneVariant(VariantManagerConstants.INITIAL_VARIANT_ID, NEW_VARIANT);
network.getVariantManager().setWorkingVariant(NEW_VARIANT);

// vl modification - assert vl name modification, linked load modification and parent subsation modification
VoltageLevelModificationInfos vlModification = ModificationCreation.getModificationVoltageLevel("v1", "v1_newname");
String vlModificationJson = mapper.writeValueAsString(vlModification);
mockMvc.perform(post(URI_NETWORK_MODIF).content(vlModificationJson).contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andReturn();

checkSomeEquipmentsVoltageLevel(NETWORK_UUID, NEW_VARIANT, "v1_newname");

// in a new variant, load modification - assert name modification - assert old data are still here
network.getVariantManager().cloneVariant(NEW_VARIANT, NEW_VARIANT_2);
network.getVariantManager().setWorkingVariant(NEW_VARIANT_2);
// vl modification - assert vl name modification, linked load modification and parent subsation modification
VoltageLevelModificationInfos vlModification2 = ModificationCreation.getModificationVoltageLevel("v1", "v1_newname_2");
String vlModification2Json = mapper.writeValueAsString(vlModification2);
mockMvc.perform(post(URI_NETWORK_MODIF).content(vlModification2Json).contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andReturn();

checkSomeEquipmentsVoltageLevel(NETWORK_UUID, NEW_VARIANT, "v1_newname");
checkSomeEquipmentsVoltageLevel(NETWORK_UUID, NEW_VARIANT_2, "v1_newname_2");
}

private void checkSomeEquipmentsVoltageLevel(UUID networkUuid, String variantId, String voltageLevelName) {
// assert targeted voltage level has been updated
assertEquals(voltageLevelName, equipmentInfosRepository.findByIdInAndNetworkUuidAndVariantId(List.of("v1"), networkUuid, variantId).get(0).getName());

// assert linked load has been updated (linked connectable)
assertTrue(checkEquipmentHasVoltageLevelWithName(networkUuid, variantId, "v1Load", voltageLevelName));

// assert linked switch has been updated (linked equipment which is not a connectable)
assertTrue(checkEquipmentHasVoltageLevelWithName(networkUuid, variantId, "v1dlcc", voltageLevelName));

// assert parent substation has been updated
assertTrue(checkEquipmentHasVoltageLevelWithName(networkUuid, variantId, "s1", voltageLevelName));
}

private boolean checkEquipmentHasVoltageLevelWithName(UUID networkUuid, String variantId, String equipmentId, String voltageLevelName) {
return equipmentInfosRepository.findByIdInAndNetworkUuidAndVariantId(List.of(equipmentId), networkUuid, variantId).get(0).getVoltageLevels().stream().anyMatch(vl -> vl.getName().equals(voltageLevelName));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package org.gridsuite.modification.server.utils;

import com.powsybl.iidm.network.EnergySource;
import com.powsybl.iidm.network.LoadType;
import com.powsybl.iidm.network.SwitchKind;
import com.powsybl.iidm.network.extensions.ConnectablePosition;
import org.gridsuite.modification.server.dto.*;
Expand Down Expand Up @@ -94,4 +95,61 @@ public static GeneratorCreationInfos getCreationGenerator(String vlId, String ge
.connectionDirection(ConnectablePosition.Direction.TOP)
.build();
}

public static LoadCreationInfos getCreationLoad(String vlId, String loadId, String loadName, String busOrBusBarSectionId, LoadType loadType) {
return LoadCreationInfos.builder()
.stashed(false)
.equipmentId(loadId)
.equipmentName(loadName)
.voltageLevelId(vlId)
.busOrBusbarSectionId(busOrBusBarSectionId)
.loadType(loadType)
.activePower(100.0)
.reactivePower(20.0)
.connectionName("top")
.connectionDirection(ConnectablePosition.Direction.TOP)
.build();
}

public static LoadModificationInfos getModificationLoad(String loadId, String vlId, String loadName, String busOrBusbarSectionId, LoadType loadType, Long activePower, Long reactivePower) {
LoadModificationInfos.LoadModificationInfosBuilder builder = LoadModificationInfos.builder()
.stashed(false)
.equipmentId(loadId);

if (loadName != null) {
builder.equipmentName(AttributeModification.toAttributeModification(loadName, OperationType.SET));
}

if (vlId != null) {
builder.voltageLevelId(AttributeModification.toAttributeModification(vlId, OperationType.SET));
}

if (busOrBusbarSectionId != null) {
builder.busOrBusbarSectionId(AttributeModification.toAttributeModification(busOrBusbarSectionId, OperationType.SET));
}

if (loadType != null) {
builder.loadType(AttributeModification.toAttributeModification(LoadType.UNDEFINED, OperationType.SET));
}

if (activePower != null) {
builder.activePower(AttributeModification.toAttributeModification(activePower, OperationType.SET));
}

if (reactivePower != null) {
builder.reactivePower(AttributeModification.toAttributeModification(reactivePower, OperationType.SET));
}

return builder.build();
}

public static VoltageLevelModificationInfos getModificationVoltageLevel(String vlId, String vlName) {
VoltageLevelModificationInfos.VoltageLevelModificationInfosBuilder builder = VoltageLevelModificationInfos.builder()
.stashed(false)
.equipmentId(vlId);

builder.equipmentName(AttributeModification.toAttributeModification(vlName, OperationType.SET));

return builder.build();
}
}

0 comments on commit b890363

Please sign in to comment.