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

Creating modifications should now impact ES index #365

Merged
merged 13 commits into from
Dec 1, 2023
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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Integration test ?

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();
}
}
Loading