Skip to content

Commit 62812e8

Browse files
adds substationOrVoltageLevelFilters to GlobalFilter (#102)
Signed-off-by: Mathieu DEHARBE <mathieu.deharbe@rte-france.com>
1 parent 6d249ff commit 62812e8

File tree

3 files changed

+100
-31
lines changed

3 files changed

+100
-31
lines changed

src/main/java/org/gridsuite/filter/globalfilter/GlobalFilter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
public class GlobalFilter {
3232
private List<String> nominalV;
3333
private List<Country> countryCode;
34+
private List<UUID> substationOrVoltageLevelFilter; // list of generic filters containing only voltage level and substation filters
3435
private List<UUID> genericFilter;
3536
private Map<String, List<String>> substationProperty;
3637

@@ -41,6 +42,7 @@ public boolean isEmpty() {
4142
return CollectionUtils.isEmpty(this.nominalV)
4243
&& CollectionUtils.isEmpty(this.countryCode)
4344
&& CollectionUtils.isEmpty(this.genericFilter)
45+
&& CollectionUtils.isEmpty(this.substationOrVoltageLevelFilter)
4446
&& (MapUtils.isEmpty(this.substationProperty) || this.substationProperty.values().stream().allMatch(CollectionUtils::isEmpty));
4547
}
4648
}

src/main/java/org/gridsuite/filter/globalfilter/GlobalFilterUtils.java

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ public static List<FieldType> getCountryCodeFieldType(@Nonnull final EquipmentTy
7070
SHUNT_COMPENSATOR, STATIC_VAR_COMPENSATOR, SUBSTATION,
7171
THREE_WINDINGS_TRANSFORMER, TWO_WINDINGS_TRANSFORMER, VOLTAGE_LEVEL, LCC_CONVERTER_STATION, VSC_CONVERTER_STATION -> List.of(FieldType.COUNTRY);
7272
case LINE, HVDC_LINE -> List.of(FieldType.COUNTRY_1, FieldType.COUNTRY_2);
73-
default -> List.of();
7473
};
7574
}
7675

@@ -150,18 +149,23 @@ public static AbstractExpertRule buildGenericFilterRule(@Nonnull final List<Abst
150149
@Nonnull final EquipmentType actualType) {
151150
final List<AbstractExpertRule> rules = new ArrayList<>();
152151

153-
// Create only one OR rule for all filters with same type (matches actualType exclude substation and voltage levels)
154-
if (actualType != EquipmentType.VOLTAGE_LEVEL && actualType != EquipmentType.SUBSTATION) {
155-
List<AbstractFilter> typeMatches = genericFilters.stream()
156-
.filter(abstractFilter -> abstractFilter.getEquipmentType() == actualType)
157-
.toList();
152+
// Create only one OR rule for all filters with same type
153+
List<AbstractFilter> typeMatches = genericFilters.stream()
154+
.filter(abstractFilter -> abstractFilter.getEquipmentType() == actualType)
155+
.toList();
158156

159-
AbstractExpertRule typeMatchesRule = createFilterBasedRule(typeMatches, Set.of(FieldType.ID));
160-
if (typeMatchesRule != null) {
161-
rules.add(typeMatchesRule);
162-
}
157+
AbstractExpertRule typeMatchesRule = createFilterBasedRule(typeMatches, Set.of(FieldType.ID));
158+
if (typeMatchesRule != null) {
159+
rules.add(typeMatchesRule);
163160
}
164161

162+
return ExpertFilterUtils.buildAndCombination(rules).orElse(null);
163+
}
164+
165+
public static AbstractExpertRule buildSubstationOrVoltageLevelFilterRule(@Nonnull final List<AbstractFilter> genericFilters,
166+
@Nonnull final EquipmentType actualType) {
167+
final List<AbstractExpertRule> rules = new ArrayList<>();
168+
165169
// Create one rule for substations and voltage levels (combined with Or)
166170
List<AbstractExpertRule> subsStationsAndVoltageLevelsRules = new ArrayList<>();
167171

@@ -204,21 +208,30 @@ public static AbstractExpertRule buildGenericFilterRule(@Nonnull final List<Abst
204208
@Nullable
205209
public static ExpertFilter buildExpertFilter(@Nonnull final GlobalFilter globalFilter,
206210
@Nonnull final EquipmentType equipmentType,
207-
@Nonnull final List<AbstractFilter> genericFilters) {
211+
@Nonnull final List<AbstractFilter> genericFilters,
212+
@Nonnull final List<AbstractFilter> substationOrVoltageLevelFilters) {
208213
final List<AbstractExpertRule> andRules = new ArrayList<>();
209214

210215
// Generic filter have a priority on other filter types
211216
if (!shouldProcessEquipmentType(equipmentType, genericFilters)) {
212217
return null;
213218
}
214219

215-
if (CollectionUtils.isNotEmpty(genericFilters)) {
220+
// substation and voltage levels are handled specifically in buildSubstationOrVoltageLevelFilterRule, they are ignored here
221+
if (CollectionUtils.isNotEmpty(genericFilters) && equipmentType != EquipmentType.VOLTAGE_LEVEL && equipmentType != EquipmentType.SUBSTATION) {
216222
AbstractExpertRule genericRule = buildGenericFilterRule(genericFilters, equipmentType);
217223
if (genericRule != null) {
218224
andRules.add(genericRule);
219225
}
220226
}
221227

228+
if (CollectionUtils.isNotEmpty(substationOrVoltageLevelFilters)) {
229+
AbstractExpertRule genericRule = buildSubstationOrVoltageLevelFilterRule(substationOrVoltageLevelFilters, equipmentType);
230+
if (genericRule != null) {
231+
andRules.add(genericRule);
232+
}
233+
}
234+
222235
if (globalFilter.getNominalV() != null) {
223236
buildNominalVoltageRules(globalFilter.getNominalV(), equipmentType).ifPresent(andRules::add);
224237
}
@@ -261,17 +274,20 @@ public static List<String> applyFilterOnNetwork(@Nonnull final AbstractFilter fi
261274
/**
262275
* Extracts filtered {@link Identifiable#getId() equipment ID}s by applying {@link ExpertFilter expert}
263276
* and {@link AbstractFilter generic filter}s.
277+
* @param genericFilters loaded filters from globalFilter.getGenericFilter() (cache)
278+
* @param substationOrVoltageLevelFilters loaded filters from globalFilter.getSubstationOrVoltageLevelFilter() (cache)
264279
*/
265280
@Nonnull
266281
public static List<String> applyGlobalFilterOnNetwork(@Nonnull final Network network,
267282
@Nonnull final GlobalFilter globalFilter,
268283
@Nonnull final EquipmentType equipmentType,
269284
final List<AbstractFilter> genericFilters,
285+
final List<AbstractFilter> substationOrVoltageLevelFilters,
270286
@Nonnull final FilterLoader filterLoader) {
271287
List<String> allFilterResults = null;
272288

273289
// Extract IDs from expert filter
274-
final ExpertFilter expertFilter = buildExpertFilter(globalFilter, equipmentType, genericFilters);
290+
final ExpertFilter expertFilter = buildExpertFilter(globalFilter, equipmentType, genericFilters, substationOrVoltageLevelFilters);
275291
if (expertFilter != null) {
276292
allFilterResults = filterNetwork(expertFilter, network, filterLoader);
277293
}
@@ -287,9 +303,10 @@ public static List<String> applyGlobalFilterOnNetwork(@Nonnull final Network net
287303
* type filters
288304
* @param equipmentType : equipment type that should be processed
289305
* @param genericFilters : generic filters list
290-
* **/
306+
* @return false if the global filter should not be processed because of the generic filters equipment types
307+
*/
291308
public static boolean shouldProcessEquipmentType(@Nonnull final EquipmentType equipmentType,
292-
@Nonnull final List<AbstractFilter>genericFilters) {
309+
@Nonnull final List<AbstractFilter> genericFilters) {
293310

294311
// The current equipment type will be process IF
295312
// list genericFilters is empty
@@ -322,13 +339,25 @@ public static Map<EquipmentType, List<String>> applyGlobalFilterOnNetwork(@Nonnu
322339
@Nonnull final FilterLoader filterLoader) {
323340
Map<EquipmentType, List<String>> result = new EnumMap<>(EquipmentType.class);
324341

325-
List<AbstractFilter> genericFilters = null;
342+
List<AbstractFilter> genericFilters = new ArrayList<>();
326343
if (CollectionUtils.isNotEmpty(globalFilter.getGenericFilter())) {
327344
genericFilters = filterLoader.getFilters(globalFilter.getGenericFilter());
328345
}
329346

347+
List<AbstractFilter> substationOrVoltageLevelFilters = new ArrayList<>();
348+
if (CollectionUtils.isNotEmpty(globalFilter.getSubstationOrVoltageLevelFilter())) {
349+
substationOrVoltageLevelFilters = filterLoader.getFilters(globalFilter.getSubstationOrVoltageLevelFilter());
350+
}
351+
330352
for (final EquipmentType equipmentType : equipmentTypes) {
331-
final List<String> filteredIds = applyGlobalFilterOnNetwork(network, globalFilter, equipmentType, genericFilters, filterLoader);
353+
final List<String> filteredIds = applyGlobalFilterOnNetwork(
354+
network,
355+
globalFilter,
356+
equipmentType,
357+
genericFilters,
358+
substationOrVoltageLevelFilters,
359+
filterLoader
360+
);
332361
if (!filteredIds.isEmpty()) {
333362
result.put(equipmentType, filteredIds);
334363
}

src/test/java/org/gridsuite/filter/globalfilter/GlobalFilterUtilsTest.java

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ void testFiltersOnOtherEquipmentTypes() {
117117
Mockito.when(voltageLevelFilter.getEquipmentType()).thenReturn(EquipmentType.VOLTAGE_LEVEL);
118118

119119
Mockito.when(loader.getFilters(genericFiltersUuids)).thenReturn(List.of(
120-
lineFilter, voltageLevelFilter));
120+
lineFilter, voltageLevelFilter));
121121

122122
List<AbstractFilter> genericFilters = loader.getFilters(genericFiltersUuids);
123123

@@ -295,16 +295,16 @@ private static Stream<Arguments> substationPropertyFieldTypeData() {
295295
class BuildExpertFilter {
296296
@Test
297297
void shouldReturnNullWhenNoExpertFiltersProvided() {
298-
final GlobalFilter globalFilter = new GlobalFilter(null, null, null, null);
299-
assertThat(GlobalFilterUtils.buildExpertFilter(globalFilter, EquipmentType.GENERATOR, List.of()))
298+
final GlobalFilter globalFilter = new GlobalFilter(null, null, null, null, null);
299+
assertThat(GlobalFilterUtils.buildExpertFilter(globalFilter, EquipmentType.GENERATOR, List.of(), List.of()))
300300
.as("result").isNull();
301301
}
302302

303303
@Test
304304
void shouldReturnNullWhenNoRules() {
305-
final GlobalFilter globalFilter = new GlobalFilter(List.of(), List.of(), List.of(), Map.of());
305+
final GlobalFilter globalFilter = new GlobalFilter(List.of(), List.of(), List.of(), List.of(), Map.of());
306306
assertTrue(globalFilter.isEmpty());
307-
assertThat(GlobalFilterUtils.buildExpertFilter(globalFilter, EquipmentType.GENERATOR, List.of()))
307+
assertThat(GlobalFilterUtils.buildExpertFilter(globalFilter, EquipmentType.GENERATOR, List.of(), List.of()))
308308
.as("result").isNull();
309309
}
310310

@@ -316,8 +316,8 @@ void shouldReturnResult() {
316316
List.of(new IdentifierListFilterEquipmentAttributes("GEN1", 50.),
317317
new IdentifierListFilterEquipmentAttributes("GEN2", 50.)
318318
)));
319-
final GlobalFilter globalFilter = new GlobalFilter(List.of("380", "225"), List.of(Country.FR, Country.BE), filterUuids, Map.of());
320-
assertThat(GlobalFilterUtils.buildExpertFilter(globalFilter, EquipmentType.GENERATOR, filters))
319+
final GlobalFilter globalFilter = new GlobalFilter(List.of("380", "225"), List.of(Country.FR, Country.BE), filterUuids, List.of(), Map.of());
320+
assertThat(GlobalFilterUtils.buildExpertFilter(globalFilter, EquipmentType.GENERATOR, filters, List.of()))
321321
.as("result").isNotNull();
322322
}
323323

@@ -329,8 +329,8 @@ void shouldReturnResultWithGenericFilterTypeDifferentFromEquipmentType() {
329329
List.of(new IdentifierListFilterEquipmentAttributes("GEN1", 50.),
330330
new IdentifierListFilterEquipmentAttributes("GEN2", 50.)
331331
)));
332-
final GlobalFilter globalFilter = new GlobalFilter(List.of("380", "225"), List.of(Country.FR, Country.BE), filterUuids, Map.of());
333-
assertThat(GlobalFilterUtils.buildExpertFilter(globalFilter, EquipmentType.GENERATOR, filters))
332+
final GlobalFilter globalFilter = new GlobalFilter(List.of("380", "225"), List.of(Country.FR, Country.BE), filterUuids, List.of(), Map.of());
333+
assertThat(GlobalFilterUtils.buildExpertFilter(globalFilter, EquipmentType.GENERATOR, List.of(), filters))
334334
.as("result").isNotNull();
335335
}
336336
}
@@ -497,7 +497,35 @@ void shouldBuildVoltageLevelFilterWhenVoltageLevelType() {
497497
final List<Identifiable<?>> attributes = List.of(line1, line2);
498498
mockedFU.when(() -> FiltersUtils.getIdentifiables(any(ExpertFilter.class), eq(network), eq(loader))).thenReturn(attributes);
499499
mockedFU.clearInvocations(); //important because stubbing static method counts as call
500-
assertThat(GlobalFilterUtils.applyGlobalFilterOnNetwork(network, globalFilter, EquipmentType.LINE, List.of(filter), loader))
500+
assertThat(GlobalFilterUtils.applyGlobalFilterOnNetwork(network, globalFilter, EquipmentType.LINE, List.of(), List.of(filter), loader))
501+
.as("result").containsExactlyInAnyOrder("line1", "line2");
502+
Mockito.verify(filter, Mockito.atLeastOnce()).getEquipmentType();
503+
Mockito.verify(filter, Mockito.atLeastOnce()).getId();
504+
Mockito.verify(line1, Mockito.atLeastOnce()).getId();
505+
Mockito.verify(line2, Mockito.atLeastOnce()).getId();
506+
Mockito.verifyNoMoreInteractions(filter, network, line1, line2);
507+
mockedFU.verify(() -> FiltersUtils.getIdentifiables(any(ExpertFilter.class), eq(network), eq(loader)), Mockito.atLeastOnce());
508+
}
509+
}
510+
511+
@Test
512+
void shouldBuildSubstationFilterWhenSubstationType() {
513+
final Network network = Mockito.mock(Network.class);
514+
final FilterLoader loader = Mockito.mock(FilterLoader.class);
515+
final AbstractFilter filter = Mockito.mock(AbstractFilter.class);
516+
final GlobalFilter globalFilter = Mockito.mock(GlobalFilter.class);
517+
when(filter.getEquipmentType()).thenReturn(EquipmentType.SUBSTATION);
518+
final UUID filterUuid = UuidUtils.createUUID(0);
519+
when(filter.getId()).thenReturn(filterUuid);
520+
try (final MockedStatic<FiltersUtils> mockedFU = Mockito.mockStatic(FiltersUtils.class, Mockito.CALLS_REAL_METHODS)) {
521+
final Identifiable<?> line1 = Mockito.mock(Identifiable.class);
522+
when(line1.getId()).thenReturn("line1");
523+
final Identifiable<?> line2 = Mockito.mock(Identifiable.class);
524+
when(line2.getId()).thenReturn("line2");
525+
final List<Identifiable<?>> attributes = List.of(line1, line2);
526+
mockedFU.when(() -> FiltersUtils.getIdentifiables(any(ExpertFilter.class), eq(network), eq(loader))).thenReturn(attributes);
527+
mockedFU.clearInvocations(); //important because stubbing static method counts as call
528+
assertThat(GlobalFilterUtils.applyGlobalFilterOnNetwork(network, globalFilter, EquipmentType.LINE, List.of(), List.of(filter), loader))
501529
.as("result").containsExactlyInAnyOrder("line1", "line2");
502530
Mockito.verify(filter, Mockito.atLeastOnce()).getEquipmentType();
503531
Mockito.verify(filter, Mockito.atLeastOnce()).getId();
@@ -515,7 +543,7 @@ void shouldReturnEmptyWhenDifferentEquipmentType() {
515543
final AbstractFilter filter = Mockito.mock(AbstractFilter.class);
516544
final GlobalFilter globalFilter = Mockito.mock(GlobalFilter.class);
517545
when(filter.getEquipmentType()).thenReturn(EquipmentType.LOAD);
518-
assertThat(GlobalFilterUtils.applyGlobalFilterOnNetwork(network, globalFilter, EquipmentType.GENERATOR, List.of(filter), loader))
546+
assertThat(GlobalFilterUtils.applyGlobalFilterOnNetwork(network, globalFilter, EquipmentType.GENERATOR, List.of(filter), List.of(), loader))
519547
.as("result").isEmpty();
520548
Mockito.verify(filter, Mockito.atLeastOnce()).getEquipmentType();
521549
Mockito.verifyNoMoreInteractions(network, filter);
@@ -540,9 +568,16 @@ void shouldReturnFilteredNetwork() {
540568
final UUID filterTransUuid = UuidUtils.createUUID(1);
541569
when(filterTrans.getId()).thenReturn(filterTransUuid);
542570

571+
final AbstractFilter filterSubstation = Mockito.mock(AbstractFilter.class);
572+
when(filterSubstation.getEquipmentType()).thenReturn(EquipmentType.SUBSTATION);
573+
final UUID filterSubstationUuid = UuidUtils.createUUID(2);
574+
when(filterSubstation.getId()).thenReturn(filterSubstationUuid);
575+
543576
final GlobalFilter globalFilter = Mockito.mock(GlobalFilter.class);
544577
List<UUID> genericFilterUuids = List.of(filterLineUuid, filterTransUuid);
545578
when(globalFilter.getGenericFilter()).thenReturn(genericFilterUuids);
579+
List<UUID> substationOrVoltageLevelFilteUuids = List.of(filterSubstationUuid);
580+
when(globalFilter.getSubstationOrVoltageLevelFilter()).thenReturn(substationOrVoltageLevelFilteUuids);
546581

547582
when(loader.getFilters(genericFilterUuids)).thenReturn(List.of(filterLine, filterTrans));
548583

@@ -612,9 +647,12 @@ void testSubstationAndVoltageLevelOnAnyEquipmentType() {
612647
when(filter2.getId()).thenReturn(filterUuids.get(1));
613648

614649
List<AbstractFilter> filters = Arrays.asList(filter1, filter2);
615-
assertNotNull(GlobalFilterUtils.buildGenericFilterRule(filters, EquipmentType.LINE));
616-
assertNotNull(GlobalFilterUtils.buildGenericFilterRule(filters, EquipmentType.GENERATOR));
617-
assertNotNull(GlobalFilterUtils.buildGenericFilterRule(filters, EquipmentType.TWO_WINDINGS_TRANSFORMER));
650+
assertNull(GlobalFilterUtils.buildGenericFilterRule(filters, EquipmentType.LINE));
651+
assertNull(GlobalFilterUtils.buildGenericFilterRule(filters, EquipmentType.GENERATOR));
652+
assertNull(GlobalFilterUtils.buildGenericFilterRule(filters, EquipmentType.TWO_WINDINGS_TRANSFORMER));
653+
assertNotNull(GlobalFilterUtils.buildSubstationOrVoltageLevelFilterRule(filters, EquipmentType.LINE));
654+
assertNotNull(GlobalFilterUtils.buildSubstationOrVoltageLevelFilterRule(filters, EquipmentType.GENERATOR));
655+
assertNotNull(GlobalFilterUtils.buildSubstationOrVoltageLevelFilterRule(filters, EquipmentType.TWO_WINDINGS_TRANSFORMER));
618656
}
619657

620658
@Test

0 commit comments

Comments
 (0)