Skip to content

Commit

Permalink
Fix recreating tombstoned identifiable/extensions
Browse files Browse the repository at this point in the history
Signed-off-by: BOUHOURS Antoine <[email protected]>
  • Loading branch information
antoinebhs committed Jan 3, 2025
1 parent e65c608 commit 7125e03
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ public Optional<ExtensionAttributes> getExtensionAttributes(
return getExtensionAttributesForVariant(connection, networkId, variantNum, identifiableId, extensionName);
}

// Retrieve extension in partial variant
Optional<ExtensionAttributes> partialVariantExtensionAttributes = getExtensionAttributesForVariant(connection, networkId, variantNum, identifiableId, extensionName);
if (partialVariantExtensionAttributes.isPresent()) {
return partialVariantExtensionAttributes;
}

// Return empty if it's a tombstoned extension or identifiable
Map<String, Set<String>> tombstonedExtensions = getTombstonedExtensions(connection, networkId, variantNum);
boolean isTombstonedExtension = tombstonedExtensions.containsKey(identifiableId) && tombstonedExtensions.get(identifiableId).contains(extensionName);
Expand All @@ -108,13 +114,7 @@ public Optional<ExtensionAttributes> getExtensionAttributes(
return Optional.empty();
}

// Retrieve extension in partial variant
Optional<ExtensionAttributes> extensionAttributes = getExtensionAttributesForVariant(connection, networkId, variantNum, identifiableId, extensionName);
if (extensionAttributes.isPresent()) {
return extensionAttributes;
}

// If not present, retrieve extension in full variant
// Retrieve extension from the full variant
return getExtensionAttributesForVariant(connection, networkId, fullVariantNum, identifiableId, extensionName);
}

Expand Down Expand Up @@ -158,19 +158,18 @@ public Map<String, ExtensionAttributes> getAllExtensionsAttributesByResourceType
// Retrieve extensions in full variant
Map<String, ExtensionAttributes> extensionsAttributesByResourceTypeAndExtensionName = getAllExtensionsAttributesByResourceTypeAndExtensionNameForVariant(connection, networkId, fullVariantNum, resourceType, extensionName);

// Remove tombstoned identifiables
// Remove tombstoned identifiables and tombstoned extensions
Set<String> tombstonedIds = tombstonedIdsSupplier.get();
extensionsAttributesByResourceTypeAndExtensionName.keySet().removeIf(tombstonedIds::contains);

// Remove tombstoned extensions
Map<String, Set<String>> tombstonedExtensions = getTombstonedExtensions(connection, networkId, variantNum);
extensionsAttributesByResourceTypeAndExtensionName.entrySet().removeIf(entry -> tombstonedExtensions.getOrDefault(entry.getKey(), Set.of()).contains(extensionName));
extensionsAttributesByResourceTypeAndExtensionName.entrySet().removeIf(entry ->
tombstonedIds.contains(entry.getKey()) ||
tombstonedExtensions.getOrDefault(entry.getKey(), Set.of()).contains(extensionName));

// Retrieve updated extensions in partial variant
Map<String, ExtensionAttributes> updatedExtensionsAttributesByResourceTypeAndExtensionName = getAllExtensionsAttributesByResourceTypeAndExtensionNameForVariant(connection, networkId, variantNum, resourceType, extensionName);
// Retrieve extensions in partial variant
Map<String, ExtensionAttributes> partialVariantExtensionsAttributesByResourceTypeAndExtensionName = getAllExtensionsAttributesByResourceTypeAndExtensionNameForVariant(connection, networkId, variantNum, resourceType, extensionName);

// Combine extensions from full and partial variants
extensionsAttributesByResourceTypeAndExtensionName.putAll(updatedExtensionsAttributesByResourceTypeAndExtensionName);
extensionsAttributesByResourceTypeAndExtensionName.putAll(partialVariantExtensionsAttributesByResourceTypeAndExtensionName);
return extensionsAttributesByResourceTypeAndExtensionName;
}

Expand Down Expand Up @@ -223,11 +222,11 @@ public Map<String, ExtensionAttributes> getAllExtensionsAttributesByIdentifiable
Map<String, Set<String>> tombstonedExtensions = getTombstonedExtensions(connection, networkId, variantNum);
extensionsAttributesByIdentifiableId.entrySet().removeIf(entry -> tombstonedExtensions.getOrDefault(identifiableId, Set.of()).contains(entry.getKey()));

// Retrieve updated extensions in partial variant
Map<String, ExtensionAttributes> updatedExtensionsAttributesByResourceTypeAndExtensionName = getAllExtensionsAttributesByIdentifiableIdForVariant(connection, networkId, variantNum, identifiableId);
// Retrieve extensions in partial variant
Map<String, ExtensionAttributes> partialVariantExtensionsAttributesByResourceTypeAndExtensionName = getAllExtensionsAttributesByIdentifiableIdForVariant(connection, networkId, variantNum, identifiableId);

// Combine extensions from full and partial variants
extensionsAttributesByIdentifiableId.putAll(updatedExtensionsAttributesByResourceTypeAndExtensionName);
extensionsAttributesByIdentifiableId.putAll(partialVariantExtensionsAttributesByResourceTypeAndExtensionName);
return extensionsAttributesByIdentifiableId;
}

Expand Down Expand Up @@ -283,11 +282,11 @@ public Map<String, Map<String, ExtensionAttributes>> getAllExtensionsAttributesB
// Remove entries with no remaining extensions after removing tombstoned extensions
extensionsAttributesByResourceType.entrySet().removeIf(entry -> entry.getValue().isEmpty());

// Retrieve updated extensions in partial variant
Map<String, Map<String, ExtensionAttributes>> updatedExtensionsAttributesByResourceType = getAllExtensionsAttributesByResourceTypeForVariant(connection, networkId, variantNum, type.toString());
// Retrieve extensions in partial variant
Map<String, Map<String, ExtensionAttributes>> partialVariantExtensionsAttributesByResourceType = getAllExtensionsAttributesByResourceTypeForVariant(connection, networkId, variantNum, type.toString());

// Combine extensions from full and partial variants
updatedExtensionsAttributesByResourceType.forEach((identifiableId, updatedExtensions) ->
partialVariantExtensionsAttributesByResourceType.forEach((identifiableId, updatedExtensions) ->
extensionsAttributesByResourceType.merge(identifiableId, updatedExtensions, (existingExtensions, newExtensions) -> {
// Merge each extension within the nested maps
newExtensions.forEach((extensionName, newExtensionAttributes) ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ private static <T, U> Map<T, U> getExternalAttributes(
additionalIdentifiableIdsToExclude.contains(idExtractor.apply(ownerInfo))
);

// Retrieve updated external attributes in partial variant
Map<T, U> externalAttributesUpdatedInPartialVariant = fetchExternalAttributesInVariant.apply(variantNum);
// Retrieve external attributes in partial variant
Map<T, U> partialVariantExternalAttributes = fetchExternalAttributesInVariant.apply(variantNum);

// Combine external attributes from full and partial variant
externalAttributes.putAll(externalAttributesUpdatedInPartialVariant);
externalAttributes.putAll(partialVariantExternalAttributes);

return externalAttributes;
}
Expand All @@ -97,15 +97,15 @@ public static <T, U> Map<T, U> getRegulatingEquipments(
int fullVariantNum,
Supplier<Set<String>> fetchTombstonedRegulatingPointsIds,
Supplier<Set<String>> fetchTombstonedIdentifiableIds,
Supplier<Set<String>> fetchUpdatedRegulatingPointIds,
Supplier<Set<String>> fetchRegulatingPointIdsInVariant,
IntFunction<Map<T, U>> fetchExternalAttributesInVariant,
Function<T, String> idExtractor) {
return getExternalAttributes(
variantNum,
fullVariantNum,
fetchTombstonedRegulatingPointsIds,
fetchTombstonedIdentifiableIds,
fetchUpdatedRegulatingPointIds,
fetchRegulatingPointIdsInVariant,
fetchExternalAttributesInVariant,
idExtractor
);
Expand Down Expand Up @@ -150,7 +150,7 @@ public static <T> List<T> getIdentifiables(
Supplier<Set<String>> fetchTombstonedIdentifiableIds,
IntFunction<List<T>> fetchIdentifiablesInVariant,
Function<T, String> idExtractor,
Supplier<List<String>> fetchUpdatedIdentifiblesIdsInVariant) {
Supplier<List<String>> fetchIdentifiblesIdsInVariant) {
if (NetworkAttributes.isFullVariant(fullVariantNum)) {
// If the variant is full, retrieve identifiables directly
return fetchIdentifiablesInVariant.apply(variantNum);
Expand All @@ -159,24 +159,24 @@ public static <T> List<T> getIdentifiables(
// Retrieve identifiables from the full variant first
List<T> identifiables = fetchIdentifiablesInVariant.apply(fullVariantNum);

// Retrieve updated identifiables in partial variant
List<T> updatedIdentifiables = fetchIdentifiablesInVariant.apply(variantNum);
// Retrieve identifiables in partial variant
List<T> partialVariantIdentifiables = fetchIdentifiablesInVariant.apply(variantNum);

// Retrieve updated ids in partial variant
Set<String> updatedIds = fetchUpdatedIdentifiblesIdsInVariant != null
? new HashSet<>(fetchUpdatedIdentifiblesIdsInVariant.get())
: updatedIdentifiables.stream()
// Retrieve ids in partial variant
Set<String> partialVariantIds = fetchIdentifiblesIdsInVariant != null
? new HashSet<>(fetchIdentifiblesIdsInVariant.get())
: partialVariantIdentifiables.stream()
.map(idExtractor)
.collect(Collectors.toSet());

// Remove any resources that have been updated in the current variant or tombstoned
// Remove any resources in the partial variant or tombstoned
Set<String> tombstonedIds = fetchTombstonedIdentifiableIds.get();
identifiables.removeIf(resource ->
updatedIds.contains(idExtractor.apply(resource)) || tombstonedIds.contains(idExtractor.apply(resource))
partialVariantIds.contains(idExtractor.apply(resource)) || tombstonedIds.contains(idExtractor.apply(resource))
);

// Combine identifiables from full and partial variant
identifiables.addAll(updatedIdentifiables);
identifiables.addAll(partialVariantIdentifiables);

return identifiables;
}
Expand All @@ -192,18 +192,18 @@ public static <T extends Attributes> Optional<Resource<T>> getOptionalIdentifiab
return fetchIdentifiableInVariant.apply(variantNum);
}

// If the identifiable is tombstoned, return directly
// Retrieve identifiable in partial variant
Optional<Resource<T>> partialVariantIdentifiable = fetchIdentifiableInVariant.apply(variantNum);
if (partialVariantIdentifiable.isPresent()) {
return partialVariantIdentifiable;
}

Set<String> tombstonedIds = fetchTombstonedIdentifiableIds.get();
if (tombstonedIds.contains(identifiableId)) {
// Return empty if the identifiable is marked as tombstoned
return Optional.empty();
}

// Retrieve updated identifiable in partial variant
Optional<Resource<T>> updatedIdentifiable = fetchIdentifiableInVariant.apply(variantNum);
if (updatedIdentifiable.isPresent()) {
return updatedIdentifiable;
}

// Retrieve identifiable from the full variant
return fetchIdentifiableInVariant.apply(fullVariantNum);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,16 @@ void getExternalAttributesFromPartialCloneWithUpdatedIdentifiableWithoutExternal
assertNull(networkStoreRepository.getTemporaryLimits(NETWORK_UUID, 1, EQUIPMENT_ID_COLUMN, lineId).get(ownerInfoLine));
assertNull(networkStoreRepository.getPermanentLimits(NETWORK_UUID, 1, EQUIPMENT_ID_COLUMN, lineId).get(ownerInfoLine));
assertNull(networkStoreRepository.getReactiveCapabilityCurvePoints(NETWORK_UUID, 1, EQUIPMENT_ID_COLUMN, genId).get(ownerInfoGen));
// Set again a tombstone to verify that it does not throw
updateExternalAttributesWithTombstone(1, lineId, genId, twoWTId);
assertNull(networkStoreRepository.getTapChangerSteps(NETWORK_UUID, 1, EQUIPMENT_ID_COLUMN, twoWTId).get(ownerInfoTwoWT));
assertNull(networkStoreRepository.getTemporaryLimits(NETWORK_UUID, 1, EQUIPMENT_ID_COLUMN, lineId).get(ownerInfoLine));
assertNull(networkStoreRepository.getPermanentLimits(NETWORK_UUID, 1, EQUIPMENT_ID_COLUMN, lineId).get(ownerInfoLine));
assertNull(networkStoreRepository.getReactiveCapabilityCurvePoints(NETWORK_UUID, 1, EQUIPMENT_ID_COLUMN, genId).get(ownerInfoGen));
// Recreate the external attributes and verify that the tombstone is ignored
updateExternalAttributes(1, lineId, genId, twoWTId, loadId);
verifyUpdatedExternalAttributes(lineId, genId, twoWTId, loadId, 1, NETWORK_UUID);
// Set again a tombstone after recreating the external attributes
updateExternalAttributesWithTombstone(1, lineId, genId, twoWTId);
assertNull(networkStoreRepository.getTapChangerSteps(NETWORK_UUID, 1, EQUIPMENT_ID_COLUMN, twoWTId).get(ownerInfoTwoWT));
assertNull(networkStoreRepository.getTemporaryLimits(NETWORK_UUID, 1, EQUIPMENT_ID_COLUMN, lineId).get(ownerInfoLine));
Expand Down Expand Up @@ -986,10 +996,20 @@ void createExtensionWithRecreatedTombstonedExtension() {
extensionAttributesMap = Map.of(ActivePowerControl.NAME, buildActivePowerControlAttributes(8.4));
insertExtensions(Map.of(ownerInfo2, extensionAttributesMap));

// Variant 1 (removed line1)
// Variant 1 (removed ActivePowerControl extensions)
Assertions.assertEquals(Optional.empty(), networkStoreRepository.getExtensionAttributes(NETWORK_UUID, 1, lineId, ActivePowerControl.NAME));
Assertions.assertEquals(Optional.of(buildOperatingStatusAttributes("status1")), networkStoreRepository.getExtensionAttributes(NETWORK_UUID, 1, lineId, OperatingStatus.NAME));
Assertions.assertEquals(Map.of(lineId, Map.of(OperatingStatus.NAME, buildOperatingStatusAttributes("status1"))), networkStoreRepository.getAllExtensionsAttributesByResourceType(NETWORK_UUID, 1, ResourceType.LINE));
Assertions.assertEquals(Map.of(), networkStoreRepository.getAllExtensionsAttributesByResourceTypeAndExtensionName(NETWORK_UUID, 1, ResourceType.LINE, ActivePowerControl.NAME));
Assertions.assertEquals(Map.of(lineId, buildOperatingStatusAttributes("status1")), networkStoreRepository.getAllExtensionsAttributesByResourceTypeAndExtensionName(NETWORK_UUID, 1, ResourceType.LINE, OperatingStatus.NAME));
Assertions.assertEquals(Map.of(OperatingStatus.NAME, buildOperatingStatusAttributes("status1")), networkStoreRepository.getAllExtensionsAttributesByIdentifiableId(NETWORK_UUID, 1, lineId));
Assertions.assertEquals(Map.of(lineId, Set.of(ActivePowerControl.NAME)), getTombstonedExtensions(NETWORK_UUID, 1));
// Variant 2 (recreated line1 with different attributes)
// Variant 2 (recreated ActivePowerControl with different attributes)
Assertions.assertEquals(Optional.of(buildActivePowerControlAttributes(8.4)), networkStoreRepository.getExtensionAttributes(NETWORK_UUID, 2, lineId, ActivePowerControl.NAME));
Assertions.assertEquals(Optional.of(buildOperatingStatusAttributes("status1")), networkStoreRepository.getExtensionAttributes(NETWORK_UUID, 2, lineId, OperatingStatus.NAME));
Assertions.assertEquals(Map.of(lineId, Map.of(OperatingStatus.NAME, buildOperatingStatusAttributes("status1"), ActivePowerControl.NAME, buildActivePowerControlAttributes(8.4))), networkStoreRepository.getAllExtensionsAttributesByResourceType(NETWORK_UUID, 2, ResourceType.LINE));
Assertions.assertEquals(Map.of(lineId, buildActivePowerControlAttributes(8.4)), networkStoreRepository.getAllExtensionsAttributesByResourceTypeAndExtensionName(NETWORK_UUID, 2, ResourceType.LINE, ActivePowerControl.NAME));
Assertions.assertEquals(Map.of(lineId, buildOperatingStatusAttributes("status1")), networkStoreRepository.getAllExtensionsAttributesByResourceTypeAndExtensionName(NETWORK_UUID, 2, ResourceType.LINE, OperatingStatus.NAME));
Assertions.assertEquals(Map.of(OperatingStatus.NAME, buildOperatingStatusAttributes("status1"), ActivePowerControl.NAME, buildActivePowerControlAttributes(8.4)), networkStoreRepository.getAllExtensionsAttributesByIdentifiableId(NETWORK_UUID, 2, lineId));
Assertions.assertEquals(Map.of(lineId, Set.of(ActivePowerControl.NAME)), getTombstonedExtensions(NETWORK_UUID, 2));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,9 @@ void createIdentifiablesWithRecreatedTombstonedIdentifiable() {
assertTrue(getIdentifiableIdsForVariant(NETWORK_UUID, 1).isEmpty());
assertEquals(Set.of(lineId1), getTombstonedIdentifiableIds(NETWORK_UUID, 1));
// Variant 2 (recreated line1 with different attributes)
assertEquals(Optional.of(lineVariant2), networkStoreRepository.getLine(NETWORK_UUID, 2, lineId1));
assertEquals(List.of(), networkStoreRepository.getVoltageLevelLines(NETWORK_UUID, 2, "vl1"));
assertEquals(List.of(lineVariant2), networkStoreRepository.getVoltageLevelLines(NETWORK_UUID, 2, "vl2"));
assertEquals(List.of(lineVariant2), networkStoreRepository.getLines(NETWORK_UUID, 2));
assertEquals(List.of(lineVariant2), getIdentifiablesForVariant(NETWORK_UUID, 2, mappings.getLineMappings()));
assertEquals(List.of(lineId1), getIdentifiableIdsForVariant(NETWORK_UUID, 2));
Expand Down

0 comments on commit 7125e03

Please sign in to comment.