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 @@ -17,6 +17,7 @@
import org.springframework.lang.NonNull;

import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand Down Expand Up @@ -102,4 +103,33 @@ public static Set<SubstationInfos> getSubstationsInfos(@NonNull Identifiable<?>
.collect(Collectors.toSet());
}

public static EquipmentInfos toInfosWithUpdatedVoltageLevelName(Identifiable<?> linkedEquipment, VoltageLevel updatedVoltageLevel, UUID networkUuid, String variantId) {
return EquipmentInfos.builder()
.networkUuid(networkUuid)
.variantId(variantId)
.id(linkedEquipment.getId())
.name(linkedEquipment.getNameOrId())
.type(linkedEquipment.getType().name())
.substations(EquipmentInfos.getSubstationsInfos(linkedEquipment))
.voltageLevels(EquipmentInfos.getVoltageLevelsInfos(linkedEquipment).stream()
.map(vl -> vl.getId().equals(updatedVoltageLevel.getId())
? VoltageLevelInfos.builder().id(vl.getId()).name(updatedVoltageLevel.getNameOrId()).build()
: vl).collect(Collectors.toSet()))
.build();
}

public static EquipmentInfos toInfosWithUpdatedSubstationName(Identifiable<?> linkedEquipment, Substation updatedSubstation, UUID networkUuid, String variantId) {
return EquipmentInfos.builder()
.networkUuid(networkUuid)
.variantId(variantId)
.id(linkedEquipment.getId())
.name(linkedEquipment.getNameOrId())
.type(linkedEquipment.getType().name())
.substations(EquipmentInfos.getSubstationsInfos(linkedEquipment).stream()
.map(s -> s.getId().equals(updatedSubstation.getId())
? SubstationInfos.builder().id(s.getId()).name(updatedSubstation.getNameOrId()).build()
: s).collect(Collectors.toSet()))
.voltageLevels(EquipmentInfos.getVoltageLevelsInfos(linkedEquipment))
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public interface EquipmentInfosRepository extends ElasticsearchRepository<Equipm

List<EquipmentInfos> findByIdInAndNetworkUuidAndVariantId(@NonNull List<String> equipmentIds, @NonNull UUID networkUuid, @NonNull String variantId);

EquipmentInfos findByIdAndNetworkUuid/*AndVariantId*/(@NonNull String equipmentId, @NonNull UUID networkUuid/*, @NonNull String variantId*/);
Copy link
Contributor

Choose a reason for hiding this comment

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

Forgot to clean it ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed


void deleteAllByNetworkUuidAndVariantId(UUID networkUuid, String variantId);

void deleteByIdInAndNetworkUuidAndVariantId(@NonNull List<String> equipmentIds, @NonNull UUID networkUuid, @NonNull String variantId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package org.gridsuite.modification.server.elasticsearch;

import com.google.common.collect.Lists;
import com.powsybl.iidm.network.Identifiable;
import org.gridsuite.modification.server.dto.elasticsearch.EquipmentInfos;
import org.gridsuite.modification.server.dto.elasticsearch.TombstonedEquipmentInfos;
import org.springframework.beans.factory.annotation.Value;
Expand Down Expand Up @@ -88,4 +89,18 @@ public void deleteAll() {
equipmentInfosRepository.deleteAll();
tombstonedEquipmentInfosRepository.deleteAll();
}

public void updateEquipment(Identifiable<?> identifiable, UUID networkUuid, String variantId) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

EquipmentInfos equipmentToUpdate = 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();

equipmentInfosRepository.save(equipmentToUpdate);
}
}
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 @@ -92,18 +93,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 +119,68 @@ public void onElementReplaced(Identifiable identifiable, String attribute, Objec
addSimpleModificationImpact(identifiable);
}

@Override
public void onUpdate(Identifiable identifiable, String attribute, Object oldValue, Object newValue) {
networkImpacts.add(
Copy link
Contributor

Choose a reason for hiding this comment

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

addSimpleModificationImpact ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is not my code, but fixed anyway

SimpleElementImpact.builder()
.impactType(SimpleElementImpact.SimpleImpactType.MODIFICATION)
.elementType(identifiable.getType())
.elementId(identifiable.getId())
.substationIds(getSubstationIds(identifiable))
.build()
);
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) {
equipmentInfosService.updateEquipment(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()) {
createdEquipments.add(EquipmentInfos.toInfosWithUpdatedVoltageLevelName(linkedSubstation.get(), updatedVoltageLevel, networkUuid, network.getVariantManager().getWorkingVariantId()));
Copy link
Contributor

Choose a reason for hiding this comment

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

If I understood well, maybe rename createdEquipments into createdOrUpdatedEquipments ? Or use a new list updatedEquipments ?
It's consufing to me, it took some time to understand why do you do add on a list named createdEquipments (I don't know this class and no Javadoc so not easy to get in)

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes use modifedEquipments list ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

}
} else if (identifiable.getType().equals(IdentifiableType.SUBSTATION)) {
Substation updatedSubstation = network.getSubstation(identifiable.getId());
Iterable<VoltageLevel> linkedVoltageLevels = updatedSubstation.getVoltageLevels();
// update all voltageLevels linked to substation
linkedVoltageLevels.forEach(vl -> createdEquipments.add(EquipmentInfos.toInfosWithUpdatedSubstationName(vl, updatedSubstation, networkUuid, network.getVariantManager().getWorkingVariantId())));
// update all equipments linked to each of the voltageLevels
linkedVoltageLevels.forEach(vl ->
Iterables.concat(
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe you can extract this part into a method like you did for updateEquipmentsLinkedToVoltageLevel ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

vl.getConnectables(),
vl.getSwitches()
).forEach(c ->
createdEquipments.add(EquipmentInfos.toInfosWithUpdatedSubstationName(c, updatedSubstation, networkUuid, network.getVariantManager().getWorkingVariantId()))
)
);
}
}

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

@Override
Expand Down
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));
}
}
Loading