Skip to content

Commit

Permalink
Delete equipments by filter
Browse files Browse the repository at this point in the history
Add support for deleting equipments by filter

Signed-off-by: BOUHOURS Antoine <[email protected]>
  • Loading branch information
antoinebhs committed Dec 8, 2023
1 parent 6d5d096 commit 714bcec
Show file tree
Hide file tree
Showing 8 changed files with 287 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public enum ModificationType {
GENERATOR_CREATION(PreloadingStrategy.NONE),
GENERATOR_MODIFICATION(PreloadingStrategy.NONE),
EQUIPMENT_DELETION(PreloadingStrategy.NONE),
BY_FILTER_DELETION(PreloadingStrategy.NONE),
LINE_CREATION(PreloadingStrategy.NONE),
LINE_MODIFICATION(PreloadingStrategy.NONE),
TWO_WINDINGS_TRANSFORMER_CREATION(PreloadingStrategy.NONE),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public enum Type {
CREATE_SHUNT_COMPENSATOR_ERROR(HttpStatus.INTERNAL_SERVER_ERROR),
MODIFY_SHUNT_COMPENSATOR_ERROR(HttpStatus.INTERNAL_SERVER_ERROR),
DELETE_EQUIPMENT_ERROR(HttpStatus.INTERNAL_SERVER_ERROR),
BY_FILTER_DELETION_ERROR(HttpStatus.INTERNAL_SERVER_ERROR),
EQUIPMENT_NOT_FOUND(HttpStatus.NOT_FOUND),
ATTRIBUTE_NOT_EDITABLE(HttpStatus.BAD_REQUEST),
CREATE_LINE_ERROR(HttpStatus.INTERNAL_SERVER_ERROR),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
Copyright (c) 2023, 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.dto;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.powsybl.commons.reporter.Reporter;
import com.powsybl.commons.reporter.ReporterModel;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
import org.gridsuite.modification.server.dto.annotation.ModificationErrorTypeName;
import org.gridsuite.modification.server.entities.equipment.deletion.ByFilterDeletionEntity;
import org.gridsuite.modification.server.modifications.AbstractModification;
import org.gridsuite.modification.server.modifications.ByFilterDeletion;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* @author Antoine Bouhours <antoine.bouhours at rte-france.com>
*/
@SuperBuilder
@NoArgsConstructor
@Getter
@Setter
@ToString(callSuper = true)
@Schema(description = "By filter deletion")
@JsonTypeName("BY_FILTER_DELETION")
@ModificationErrorTypeName("BY_FILTER_DELETION_ERROR")
public class ByFilterDeletionInfos extends ModificationInfos {
@Schema(description = "Equipment type")
private String equipmentType;

@Schema(description = "Equipment filters")
@JsonInclude(JsonInclude.Include.NON_NULL)
private List<FilterInfos> equipmentFilters;

@Override
public ByFilterDeletionEntity toEntity() {
return new ByFilterDeletionEntity(this);
}

@Override
public AbstractModification toModification() {
return new ByFilterDeletion(this);
}

@Override
public Reporter createSubReporter(ReporterModel reporter) {
return reporter.createSubReporter(getType().name(), "By filter deletion");
}

@Override
public Map<String, String> getMapMessageValues() {
Map<String, String> mapMessageValues = new HashMap<>();
mapMessageValues.put("equipmentType", getEquipmentType());
return mapMessageValues;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
@JsonSubTypes.Type(value = TwoWindingsTransformerCreationInfos.class),
@JsonSubTypes.Type(value = TwoWindingsTransformerModificationInfos.class),
@JsonSubTypes.Type(value = EquipmentDeletionInfos.class),
@JsonSubTypes.Type(value = ByFilterDeletionInfos.class),
@JsonSubTypes.Type(value = LineSplitWithVoltageLevelInfos.class),
@JsonSubTypes.Type(value = LineAttachToVoltageLevelInfos.class),
@JsonSubTypes.Type(value = LinesAttachToSplitLinesInfos.class),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
Copyright (c) 2023, 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.entities.equipment.deletion;

import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import org.gridsuite.modification.server.dto.ByFilterDeletionInfos;
import org.gridsuite.modification.server.dto.FilterInfos;
import org.gridsuite.modification.server.dto.ModificationInfos;
import org.gridsuite.modification.server.entities.ModificationEntity;
import org.gridsuite.modification.server.entities.equipment.modification.VariationFilterEntity;

import java.util.List;
import java.util.stream.Collectors;

/**
* @author Antoine Bouhours <antoine.bouhours at rte-france.com>
*/
@NoArgsConstructor
@Getter
@Entity
@Table(name = "byFilterDeletion")
@PrimaryKeyJoinColumn(foreignKey = @ForeignKey(name = "ByFilterDeletion_id_fk_constraint"))
public class ByFilterDeletionEntity extends ModificationEntity {
@Column(name = "equipmentType")
private String equipmentType;

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
@JoinTable(
joinColumns = @JoinColumn(name = "id"),
inverseJoinColumns = @JoinColumn(name = "filterId"))
private List<VariationFilterEntity> equipmentFilters;

public ByFilterDeletionEntity(ByFilterDeletionInfos byFilterDeletionInfos) {
super(byFilterDeletionInfos);
assignAttributes(byFilterDeletionInfos);
}

@Override
public void update(@NonNull ModificationInfos modificationInfos) {
super.update(modificationInfos);
assignAttributes((ByFilterDeletionInfos) modificationInfos);
}

private void assignAttributes(ByFilterDeletionInfos byFilterDeletionInfos) {
this.equipmentType = byFilterDeletionInfos.getEquipmentType();
if (equipmentFilters == null) {
this.equipmentFilters = byFilterDeletionInfos.getEquipmentFilters().stream().map(FilterInfos::toEntity).collect(Collectors.toList());
} else {
equipmentFilters.clear();
equipmentFilters.addAll(byFilterDeletionInfos.getEquipmentFilters().stream().map(FilterInfos::toEntity).collect(Collectors.toList()));
}
}

@Override
public ByFilterDeletionInfos toModificationInfos() {
return ByFilterDeletionInfos
.builder()
.uuid(getId())
.date(getDate())
.stashed(getStashed())
.equipmentFilters(this.getEquipmentFilters().stream()
.map(filter -> new FilterInfos(filter.getFilterId(), filter.getName()))
.collect(Collectors.toList()))
.equipmentType(getEquipmentType()).build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/**
* Copyright (c) 2023, 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.modifications;

import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.reporter.Report;
import com.powsybl.commons.reporter.Reporter;
import com.powsybl.commons.reporter.TypedValue;
import com.powsybl.iidm.modification.topology.RemoveFeederBay;
import com.powsybl.iidm.modification.topology.RemoveSubstationBuilder;
import com.powsybl.iidm.modification.topology.RemoveVoltageLevel;
import com.powsybl.iidm.network.IdentifiableType;
import com.powsybl.iidm.network.Network;
import org.gridsuite.modification.server.dto.ByFilterDeletionInfos;
import org.gridsuite.modification.server.dto.FilterEquipments;
import org.gridsuite.modification.server.dto.FilterInfos;
import org.gridsuite.modification.server.dto.IdentifiableAttributes;
import org.gridsuite.modification.server.service.FilterService;
import org.springframework.util.CollectionUtils;

import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

import static org.gridsuite.modification.server.modifications.ModificationUtils.createReport;
import static org.gridsuite.modification.server.modifications.ModificationUtils.distinctByKey;

/**
* @author Antoine Bouhours <antoine.bouhours at rte-france.com>
*/
public class ByFilterDeletion extends AbstractModification {

private final ByFilterDeletionInfos modificationInfos;

protected FilterService filterService;

private static final EnumSet<IdentifiableType> CONNECTABLE_EQUIPMENTS = EnumSet.of(
IdentifiableType.LINE,
IdentifiableType.TWO_WINDINGS_TRANSFORMER,
IdentifiableType.THREE_WINDINGS_TRANSFORMER,
IdentifiableType.GENERATOR,
IdentifiableType.BATTERY,
IdentifiableType.LOAD,
IdentifiableType.SHUNT_COMPENSATOR,
IdentifiableType.DANGLING_LINE,
IdentifiableType.STATIC_VAR_COMPENSATOR
);
public ByFilterDeletion(ByFilterDeletionInfos modificationInfos) {
this.modificationInfos = modificationInfos;
}

@Override
public void initApplicationContext(NetworkModificationApplicator modificationApplicator) {
filterService = modificationApplicator.getFilterService();
}

@Override
public void apply(Network network, Reporter subReporter) {
var filters = modificationInfos.getEquipmentFilters().stream()
.filter(distinctByKey(FilterInfos::getId))
.collect(Collectors.toMap(FilterInfos::getId, FilterInfos::getName));

Map<UUID, FilterEquipments> exportFilters = ModificationUtils.getInstance().getUuidFilterEquipmentsMap(filterService, network, subReporter, filters, modificationInfos);
if (exportFilters == null) return;
Map<UUID, FilterEquipments> exportedFiltersWithWrongEquipmentIds = ModificationUtils.getInstance().getUuidFilterWrongEquipmentsIdsMap(subReporter, exportFilters, filters);
List<IdentifiableAttributes> identifiableAttributes = ModificationUtils.getIdentifiableAttributes(exportFilters, exportedFiltersWithWrongEquipmentIds, modificationInfos.getEquipmentFilters(), subReporter);

if (CollectionUtils.isEmpty(identifiableAttributes)) {
String filterNames = modificationInfos.getEquipmentFilters().stream().map(FilterInfos::getName).collect(Collectors.joining(", "));
createReport(subReporter,
"allFiltersWrong",
String.format("All of the following filters have equipments with wrong id : %s", filterNames),
TypedValue.WARN_SEVERITY);
} else {
applyFilterDeletion(network, subReporter, identifiableAttributes);
}

subReporter.report(Report.builder()
.withKey("equipmentDeleted")
.withDefaultMessage("equipment of type=${type} and ids=${ids} deleted")
.withValue("type", modificationInfos.getEquipmentType())
.withValue("ids", identifiableAttributes.stream().map(IdentifiableAttributes::getId).collect(Collectors.joining(", ")))
.withSeverity(TypedValue.INFO_SEVERITY)
.build());
}

private void applyFilterDeletion(Network network, Reporter subReporter, List<IdentifiableAttributes> identifiableAttributes) {
IdentifiableType identifiableType = IdentifiableType.valueOf(modificationInfos.getEquipmentType());
if (CONNECTABLE_EQUIPMENTS.contains(identifiableType)) {
identifiableAttributes.forEach(identifiableAttribute -> new RemoveFeederBay(identifiableAttribute.getId()).apply(network, true, subReporter));
} else if (identifiableType == IdentifiableType.VOLTAGE_LEVEL) {
identifiableAttributes.forEach(identifiableAttribute -> new RemoveVoltageLevel(identifiableAttribute.getId()).apply(network, true, subReporter));
} else if (identifiableType == IdentifiableType.SUBSTATION) {
identifiableAttributes.forEach(identifiableAttribute -> new RemoveSubstationBuilder().withSubstationId(identifiableAttribute.getId()).build().apply(network, true, subReporter));
} else {
throw new PowsyblException("Unsupported equipment type");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet author="bouhoursant (generated)" id="1701951681075-29">
<createTable tableName="by_filter_deletion">
<column name="equipment_type" type="VARCHAR(255)"/>
<column name="id" type="UUID">
<constraints nullable="false" primaryKey="true" primaryKeyName="by_filter_deletionPK"/>
</column>
</createTable>
</changeSet>
<changeSet author="bouhoursant (generated)" id="1701951681075-30">
<createTable tableName="by_filter_deletion_equipment_filters">
<column name="id" type="UUID">
<constraints nullable="false"/>
</column>
<column name="filter_id" type="UUID">
<constraints nullable="false"/>
</column>
</createTable>
</changeSet>
<changeSet author="bouhoursant (generated)" id="1701951681075-31">
<addUniqueConstraint columnNames="filter_id" constraintName="UC_BY_FILTER_DELETION_EQUIPMENT_FILTERSFILTER_ID_COL" tableName="by_filter_deletion_equipment_filters"/>
</changeSet>
<changeSet author="bouhoursant (generated)" id="1701951681075-46">
<addForeignKeyConstraint baseColumnNames="id" baseTableName="by_filter_deletion" constraintName="ByFilterDeletion_id_fk_constraint" deferrable="false" initiallyDeferred="false" referencedColumnNames="id" referencedTableName="modification" validate="true"/>
</changeSet>
<changeSet author="bouhoursant (generated)" id="1701951681075-47">
<addForeignKeyConstraint baseColumnNames="filter_id" baseTableName="by_filter_deletion_equipment_filters" constraintName="FK6mdj9n0jqovnp8k7uv2dvudf3" deferrable="false" initiallyDeferred="false" referencedColumnNames="id" referencedTableName="variation_filter" validate="true"/>
</changeSet>
<changeSet author="bouhoursant (generated)" id="1701951681075-48">
<addForeignKeyConstraint baseColumnNames="id" baseTableName="by_filter_deletion_equipment_filters" constraintName="FKamud9vd6dj9jvojrg0l070ijm" deferrable="false" initiallyDeferred="false" referencedColumnNames="id" referencedTableName="by_filter_deletion" validate="true"/>
</changeSet>
</databaseChangeLog>
3 changes: 3 additions & 0 deletions src/main/resources/db/changelog/db.changelog-master.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -224,4 +224,7 @@ databaseChangeLog:
relativeToChangelogFile: true
- include:
file: changesets/changelog_20231117T175127Z.xml
relativeToChangelogFile: true
- include:
file: changesets/changelog_20231207T122105Z.xml
relativeToChangelogFile: true

0 comments on commit 714bcec

Please sign in to comment.