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

Add by filter deletion #390

Merged
merged 22 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.COLLECTION),
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,69 @@
/*
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 com.powsybl.iidm.network.IdentifiableType;
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 IdentifiableType equipmentType;

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

@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().name());
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,76 @@
/*
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 com.powsybl.iidm.network.IdentifiableType;
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 = "by_filter_deletion_id_fk_constraint"))
public class ByFilterDeletionEntity extends ModificationEntity {
@Enumerated(EnumType.STRING)
@Column(name = "equipmentType")
private IdentifiableType equipmentType;

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
@JoinTable(
antoinebhs marked this conversation as resolved.
Show resolved Hide resolved
name = "byFilterDeletionFilters",
joinColumns = @JoinColumn(name = "id"), foreignKey = @ForeignKey(name = "by_filter_deletion_id_fk"),
inverseJoinColumns = @JoinColumn(name = "filterId"), inverseForeignKey = @ForeignKey(name = "variation_filter_id_fk"))
private List<VariationFilterEntity> filters;

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 (filters == null) {
this.filters = byFilterDeletionInfos.getFilters().stream().map(FilterInfos::toEntity).collect(Collectors.toList());
} else {
filters.clear();
filters.addAll(byFilterDeletionInfos.getFilters().stream().map(FilterInfos::toEntity).collect(Collectors.toList()));
}
}

@Override
public ByFilterDeletionInfos toModificationInfos() {
return ByFilterDeletionInfos
.builder()
.uuid(getId())
.date(getDate())
.stashed(getStashed())
.filters(getFilters().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,107 @@
/**
* 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(
antoinebhs marked this conversation as resolved.
Show resolved Hide resolved
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.getFilters().stream()
.filter(distinctByKey(FilterInfos::getId))
.collect(Collectors.toMap(FilterInfos::getId, FilterInfos::getName));

Map<UUID, FilterEquipments> exportFilters = ModificationUtils.getUuidFilterEquipmentsMap(filterService, network, subReporter, filters, modificationInfos.getErrorType());
if (exportFilters != null) {
Map<UUID, FilterEquipments> exportedFiltersWithWrongEquipmentIds = ModificationUtils.getUuidFilterWrongEquipmentsIdsMap(subReporter, exportFilters, filters);
List<IdentifiableAttributes> identifiableAttributes = ModificationUtils.getIdentifiableAttributes(exportFilters, exportedFiltersWithWrongEquipmentIds, modificationInfos.getFilters(), subReporter);

if (CollectionUtils.isEmpty(identifiableAttributes)) {
String filterNames = modificationInfos.getFilters().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().name())
.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 = 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");
antoinebhs marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
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="1702571116809-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="1702571116809-30">
<createTable tableName="by_filter_deletion_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="1702571116809-31">
<addUniqueConstraint columnNames="filter_id" constraintName="UC_BY_FILTER_DELETION_FILTERSFILTER_ID_COL" tableName="by_filter_deletion_filters"/>
</changeSet>
<changeSet author="bouhoursant (generated)" id="1702571116809-47">
<addForeignKeyConstraint baseColumnNames="id" baseTableName="by_filter_deletion_filters" constraintName="by_filter_deletion_id_fk" deferrable="false" initiallyDeferred="false" referencedColumnNames="id" referencedTableName="by_filter_deletion" validate="true"/>
</changeSet>
<changeSet author="bouhoursant (generated)" id="1702571116809-48">
<addForeignKeyConstraint baseColumnNames="id" baseTableName="by_filter_deletion" constraintName="by_filter_deletion_id_fk_constraint" deferrable="false" initiallyDeferred="false" referencedColumnNames="id" referencedTableName="modification" validate="true"/>
</changeSet>
<changeSet author="bouhoursant (generated)" id="1702571116809-51">
<addForeignKeyConstraint baseColumnNames="filter_id" baseTableName="by_filter_deletion_filters" constraintName="variation_filter_id_fk" deferrable="false" initiallyDeferred="false" referencedColumnNames="id" referencedTableName="variation_filter" 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 @@ -227,4 +227,7 @@ databaseChangeLog:
relativeToChangelogFile: true
- include:
file: changesets/changelog_20231215T170225Z.xml
relativeToChangelogFile: true
- include:
file: changesets/changelog_20231214T162501Z.xml
relativeToChangelogFile: true
Loading
Loading