Skip to content

Refactoring: setUp. #736

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

Merged
merged 29 commits into from
May 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
aa44950
Refactoring: setUp.
AAJELLAL Apr 24, 2025
6d73e3d
Merge branch 'main' of https://github.com/gridsuite/study-server into…
AAJELLAL Apr 24, 2025
1d4de91
fix merge conflict
AAJELLAL Apr 24, 2025
734df7f
refacto stashedNode
AAJELLAL Apr 24, 2025
e3f34af
Rename node unbuilding methods
Apr 28, 2025
281d29f
Merge branch 'main' of https://github.com/powsybl/powsybl-study-serve…
Apr 28, 2025
457ef47
Unbuild a subtree
Apr 28, 2025
a4d3536
handle stashNode an change the stashChildren description.
AAJELLAL Apr 29, 2025
92df06b
handle stashNode an change the stashChildren description.
AAJELLAL Apr 29, 2025
6651fac
Refactoring the moveStudyNode.
AAJELLAL Apr 29, 2025
63a003e
Use sets in InvalidateNodeInfos
Apr 29, 2025
9058ae9
Merge branch 'refacto-invalidate-node' of https://github.com/powsybl/…
Apr 29, 2025
1eeb82e
Refactoring the root network update..
AAJELLAL Apr 29, 2025
d4a8685
Merge branch 'refacto-invalidate-node' of https://github.com/gridsuit…
AAJELLAL Apr 29, 2025
f281dd3
Fix stash test
Apr 29, 2025
7a05ae9
Refactoring the root network update..
AAJELLAL Apr 29, 2025
c3f34d3
Merge branch 'refacto-invalidate-node' of https://github.com/gridsuit…
AAJELLAL Apr 29, 2025
18c5469
Refactor testUpdateRootNetworkConsumer to remove invalidateBuild
AAJELLAL Apr 29, 2025
9738ac8
Merge branch 'main' of https://github.com/gridsuite/study-server into…
AAJELLAL Apr 29, 2025
a76c5da
Fix test.
AAJELLAL Apr 29, 2025
a7ef260
Merge branch 'main' of https://github.com/gridsuite/study-server into…
AAJELLAL Apr 29, 2025
69b2a09
Merge branch 'main' into refacto-invalidate-node
AAJELLAL Apr 30, 2025
1325c2f
Merge branch 'main' of https://github.com/powsybl/powsybl-study-serve…
May 4, 2025
4863462
Remove updateStatuses method (first one)
May 4, 2025
0dff488
Renaming
May 4, 2025
c9e1245
Remove updateStatuses method (last one)
May 4, 2025
e667181
Merge branch 'main' into refacto-invalidate-node
AAJELLAL May 5, 2025
f31b034
Remove old comments
May 5, 2025
c1a9848
Merge branch 'refacto-invalidate-node' of https://github.com/powsybl/…
May 5, 2025
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 @@ -1379,7 +1379,7 @@ public ResponseEntity<Void> deleteNode(@Parameter(description = "study uuid") @P
@ApiResponse(responseCode = "404", description = "The study or the node not found")})
public ResponseEntity<Void> stashNode(@Parameter(description = "study uuid") @PathVariable("studyUuid") UUID studyUuid,
@Parameter(description = "id of child to delete (move to trash)") @PathVariable("id") UUID nodeId,
@Parameter(description = "stashChildren") @RequestParam(value = "stashChildren", defaultValue = "false") boolean stashChildren,
@Parameter(description = "to stash a node with its children") @RequestParam(value = "stashChildren", defaultValue = "false") boolean stashChildren,
@RequestHeader(HEADER_USER_ID) String userId) {
studyService.stashNode(studyUuid, nodeId, stashChildren, userId);
return ResponseEntity.ok().build();
Expand Down Expand Up @@ -1513,7 +1513,7 @@ public ResponseEntity<Void> buildNode(@Parameter(description = "Study uuid") @Pa
public ResponseEntity<Void> unbuildNode(@Parameter(description = "Study uuid") @PathVariable("studyUuid") UUID studyUuid,
@Parameter(description = "rootNetworkUuid") @PathVariable("rootNetworkUuid") UUID rootNetworkUuid,
@Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) {
studyService.unbuildNode(studyUuid, nodeUuid, rootNetworkUuid);
studyService.unbuildStudyNode(studyUuid, nodeUuid, rootNetworkUuid);
return ResponseEntity.ok().build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public ResponseEntity<Void> reindexStudy(@Parameter(description = "study uuid")
@Operation(summary = "Invalidate node builds for the given study")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "all built nodes for the given study have been invalidated")})
public ResponseEntity<Void> invalidateAllNodesBuilds(@PathVariable("studyUuid") UUID studyUuid) {
supervisionService.invalidateAllNodesBuilds(studyUuid);
supervisionService.unbuildAllNodes(studyUuid);
return ResponseEntity.ok().build();
}

Expand Down
113 changes: 94 additions & 19 deletions src/main/java/org/gridsuite/study/server/dto/InvalidateNodeInfos.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,93 @@
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

/**
* @author Nicolas Noir <nicolas.noir at rte-france.com>
*/

@NoArgsConstructor
@Getter
@Setter
public class InvalidateNodeInfos {
@Getter
@Setter
private UUID networkUuid;

private List<UUID> reportUuids = new ArrayList<>();
private Set<UUID> nodeUuids = new HashSet<>();
private Set<UUID> groupUuids = new HashSet<>();

private Set<UUID> reportUuids = new HashSet<>();
private Set<String> variantIds = new HashSet<>();

private Set<UUID> loadFlowResultUuids = new HashSet<>();
private Set<UUID> securityAnalysisResultUuids = new HashSet<>();
private Set<UUID> sensitivityAnalysisResultUuids = new HashSet<>();
private Set<UUID> nonEvacuatedEnergyResultUuids = new HashSet<>();
private Set<UUID> shortCircuitAnalysisResultUuids = new HashSet<>();
private Set<UUID> oneBusShortCircuitAnalysisResultUuids = new HashSet<>();
private Set<UUID> voltageInitResultUuids = new HashSet<>();
private Set<UUID> stateEstimationResultUuids = new HashSet<>();

private Set<UUID> dynamicSimulationResultUuids = new HashSet<>();
private Set<UUID> dynamicSecurityAnalysisResultUuids = new HashSet<>();

public List<UUID> getNodeUuids() {
return nodeUuids.stream().toList();
}

public List<UUID> getGroupUuids() {
return groupUuids.stream().toList();
}

private List<String> variantIds = new ArrayList<>();
public List<UUID> getReportUuids() {
return reportUuids.stream().toList();
}

public List<String> getVariantIds() {
return variantIds.stream().toList();
}

public List<UUID> getLoadFlowResultUuids() {
return loadFlowResultUuids.stream().toList();
}

public List<UUID> getSecurityAnalysisResultUuids() {
return securityAnalysisResultUuids.stream().toList();
}

private List<UUID> loadFlowResultUuids = new ArrayList<>();
public List<UUID> getSensitivityAnalysisResultUuids() {
return sensitivityAnalysisResultUuids.stream().toList();
}

private List<UUID> securityAnalysisResultUuids = new ArrayList<>();
public List<UUID> getNonEvacuatedEnergyResultUuids() {
return nonEvacuatedEnergyResultUuids.stream().toList();
}

private List<UUID> sensitivityAnalysisResultUuids = new ArrayList<>();
private List<UUID> nonEvacuatedEnergyResultUuids = new ArrayList<>();
public List<UUID> getShortCircuitAnalysisResultUuids() {
return shortCircuitAnalysisResultUuids.stream().toList();
}

private List<UUID> shortCircuitAnalysisResultUuids = new ArrayList<>();
private List<UUID> oneBusShortCircuitAnalysisResultUuids = new ArrayList<>();
public List<UUID> getOneBusShortCircuitAnalysisResultUuids() {
return oneBusShortCircuitAnalysisResultUuids.stream().toList();
}

private List<UUID> voltageInitResultUuids = new ArrayList<>();
public List<UUID> getVoltageInitResultUuids() {
return voltageInitResultUuids.stream().toList();
}

private List<UUID> dynamicSimulationResultUuids = new ArrayList<>();
private List<UUID> dynamicSecurityAnalysisResultUuids = new ArrayList<>();
public List<UUID> getStateEstimationResultUuids() {
return stateEstimationResultUuids.stream().toList();
}

private List<UUID> stateEstimationResultUuids = new ArrayList<>();
public List<UUID> getDynamicSimulationResultUuids() {
return dynamicSimulationResultUuids.stream().toList();
}

private List<UUID> groupUuids = new ArrayList<>();
public List<UUID> getDynamicSecurityAnalysisResultUuids() {
return dynamicSecurityAnalysisResultUuids.stream().toList();
}

public void addReportUuid(UUID reportUuid) {
reportUuids.add(reportUuid);
Expand All @@ -56,7 +107,7 @@ public void addVariantId(String variantId) {
}

public void addLoadFlowResultUuid(UUID loadFlowResultUuid) {
getLoadFlowResultUuids().add(loadFlowResultUuid);
loadFlowResultUuids.add(loadFlowResultUuid);
}

public void addSecurityAnalysisResultUuid(UUID securityAnalysisResultUuid) {
Expand Down Expand Up @@ -95,7 +146,31 @@ public void addStateEstimationResultUuid(UUID stateEstimationResultUuid) {
stateEstimationResultUuids.add(stateEstimationResultUuid);
}

public void addGroupUuid(List<UUID> groupUuids) {
public void addGroupUuids(List<UUID> groupUuids) {
this.groupUuids.addAll(groupUuids);
}

public void addNodeUuid(UUID nodeUuid) {
this.nodeUuids.add(nodeUuid);
}

public void add(InvalidateNodeInfos invalidateNodeInfos) {
nodeUuids.addAll(invalidateNodeInfos.getNodeUuids());
groupUuids.addAll(invalidateNodeInfos.getGroupUuids());

reportUuids.addAll(invalidateNodeInfos.getReportUuids());
variantIds.addAll(invalidateNodeInfos.getVariantIds());

loadFlowResultUuids.addAll(invalidateNodeInfos.getLoadFlowResultUuids());
securityAnalysisResultUuids.addAll(invalidateNodeInfos.getSecurityAnalysisResultUuids());
sensitivityAnalysisResultUuids.addAll(invalidateNodeInfos.getSensitivityAnalysisResultUuids());
nonEvacuatedEnergyResultUuids.addAll(invalidateNodeInfos.getNonEvacuatedEnergyResultUuids());
shortCircuitAnalysisResultUuids.addAll(invalidateNodeInfos.getShortCircuitAnalysisResultUuids());
oneBusShortCircuitAnalysisResultUuids.addAll(invalidateNodeInfos.getOneBusShortCircuitAnalysisResultUuids());
voltageInitResultUuids.addAll(invalidateNodeInfos.getVoltageInitResultUuids());
stateEstimationResultUuids.addAll(invalidateNodeInfos.getStateEstimationResultUuids());

dynamicSimulationResultUuids.addAll(invalidateNodeInfos.getDynamicSimulationResultUuids());
dynamicSecurityAnalysisResultUuids.addAll(invalidateNodeInfos.getDynamicSecurityAnalysisResultUuids());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ public void emitSubtreeInserted(UUID studyUuid, UUID parentNodeSubtreeInserted,
}

@PostCompletion
public void emitNodeBuildStatusUpdated(UUID studyUuid, Collection<UUID> nodes, UUID rootNetworkUuid) {
public void emitNodeBuildStatusUpdated(UUID studyUuid, List<UUID> nodes, UUID rootNetworkUuid) {
sendStudyUpdateMessage(studyUuid, NODE_BUILD_STATUS_UPDATED, MessageBuilder.withPayload("")
.setHeader(HEADER_NODES, nodes)
.setHeader(HEADER_ROOT_NETWORK_UUID, rootNetworkUuid)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,7 @@ public void invalidateBuild(UUID nodeUuid, UUID rootNetworkUuid, boolean invalid
changedNodes.add(nodeUuid);
UUID studyId = self.getStudyUuidForNodeId(nodeUuid);
nodesRepository.findById(nodeUuid).ifPresent(nodeEntity -> {
fillIndexedModificationsInfosToInvalidate(invalidateNodeInfos, nodeUuid, rootNetworkUuid, invalidateOnlyChildrenBuildStatus);
fillIndexedNodeInfosToInvalidate(invalidateNodeInfos, nodeUuid, rootNetworkUuid, invalidateOnlyChildrenBuildStatus);
if (rootNetworkService.exists(rootNetworkUuid)) {
if (nodeEntity.getType().equals(NodeType.NETWORK_MODIFICATION)) {
rootNetworkNodeInfoService.invalidateRootNetworkNodeInfoProper(nodeUuid, rootNetworkUuid, invalidateNodeInfos, invalidateOnlyChildrenBuildStatus, changedNodes, deleteVoltageInitResults);
Expand All @@ -802,10 +802,10 @@ public void invalidateBuild(UUID nodeUuid, UUID rootNetworkUuid, boolean invalid
}
});

notificationService.emitNodeBuildStatusUpdated(studyId, changedNodes.stream().distinct().collect(Collectors.toList()), rootNetworkUuid);
notificationService.emitNodeBuildStatusUpdated(studyId, changedNodes.stream().distinct().toList(), rootNetworkUuid);
}

private void fillIndexedModificationsInfosToInvalidate(InvalidateNodeInfos invalidateNodeInfos, UUID nodeUuid, UUID rootNetworkUuid, boolean invalidateOnlyChildrenBuildStatus) {
private void fillIndexedNodeInfosToInvalidate(InvalidateNodeInfos invalidateNodeInfos, UUID nodeUuid, UUID rootNetworkUuid, boolean invalidateOnlyChildrenBuildStatus) {
// when invalidating node
// we need to invalidate indexed modifications up to it's last built parent, not included
boolean isNodeBuilt = self.getNodeBuildStatus(nodeUuid, rootNetworkUuid).isBuilt();
Expand All @@ -814,13 +814,47 @@ private void fillIndexedModificationsInfosToInvalidate(InvalidateNodeInfos inval
}

if (isNodeBuilt && invalidateOnlyChildrenBuildStatus) {
fillIndexedModificationsInfosToInvalidate(nodeUuid, false, invalidateNodeInfos);
fillIndexedNodeInfosToInvalidate(nodeUuid, false, invalidateNodeInfos);
} else {
NodeEntity closestNodeWithParentHavingBuiltDescendent = getSubTreeToInvalidateIndexedModifications(nodeUuid, rootNetworkUuid);
fillIndexedModificationsInfosToInvalidate(closestNodeWithParentHavingBuiltDescendent.getIdNode(), true, invalidateNodeInfos);
fillIndexedNodeInfosToInvalidate(closestNodeWithParentHavingBuiltDescendent.getIdNode(), true, invalidateNodeInfos);
}
}

@Transactional
public InvalidateNodeInfos invalidateNode(UUID nodeUuid, UUID rootNetworkUuid) {
NodeEntity nodeEntity = getNodeEntity(nodeUuid);

InvalidateNodeInfos invalidateNodeInfos = rootNetworkNodeInfoService.invalidateRootNetworkNode(nodeUuid, rootNetworkUuid, true);

fillIndexedNodeInfosToInvalidate(nodeEntity, rootNetworkUuid, invalidateNodeInfos);

notificationService.emitNodeBuildStatusUpdated(nodeEntity.getStudy().getId(), List.of(nodeUuid), rootNetworkUuid);

return invalidateNodeInfos;
}

@Transactional
public InvalidateNodeInfos invalidateNodeTree(UUID nodeUuid, UUID rootNetworkUuid, boolean invalidateOnlyChildrenBuildStatus) {
NodeEntity nodeEntity = getNodeEntity(nodeUuid);

InvalidateNodeInfos invalidateNodeInfos = new InvalidateNodeInfos();

// First node
if (nodeEntity.getType().equals(NodeType.NETWORK_MODIFICATION)) {
invalidateNodeInfos = rootNetworkNodeInfoService.invalidateRootNetworkNode(nodeUuid, rootNetworkUuid, !invalidateOnlyChildrenBuildStatus);
fillIndexedNodeTreeInfosToInvalidate(nodeEntity, rootNetworkUuid, invalidateNodeInfos);
}

invalidateNodeInfos.add(invalidateChildrenNodes(nodeUuid, rootNetworkUuid));

if (!invalidateNodeInfos.getNodeUuids().isEmpty()) {
notificationService.emitNodeBuildStatusUpdated(nodeEntity.getStudy().getId(), invalidateNodeInfos.getNodeUuids().stream().toList(), rootNetworkUuid);
}

return invalidateNodeInfos;
}

@Transactional
// method used when moving a node to invalidate it without impacting other nodes
public void invalidateBuildOfNodeOnly(UUID nodeUuid, UUID rootNetworkUuid, boolean invalidateOnlyChildrenBuildStatus, InvalidateNodeInfos invalidateNodeInfos, boolean deleteVoltageInitResults) {
Expand All @@ -840,10 +874,10 @@ public void invalidateBuildOfNodeOnly(UUID nodeUuid, UUID rootNetworkUuid, boole
if (!hasAnyBuiltChildren(getNodeEntity(nodeUuid), rootNetworkUuid)) {
// when invalidating nodes, we need to get last built parent to invalidate all its children modifications in elasticsearch
NodeEntity closestNodeWithParentHavingBuiltDescendent = getSubTreeToInvalidateIndexedModifications(nodeUuid, rootNetworkUuid);
fillIndexedModificationsInfosToInvalidate(closestNodeWithParentHavingBuiltDescendent.getIdNode(), true, invalidateNodeInfos);
fillIndexedNodeInfosToInvalidate(closestNodeWithParentHavingBuiltDescendent.getIdNode(), true, invalidateNodeInfos);
}

notificationService.emitNodeBuildStatusUpdated(studyId, changedNodes.stream().distinct().collect(Collectors.toList()), rootNetworkUuid);
notificationService.emitNodeBuildStatusUpdated(studyId, changedNodes.stream().distinct().toList(), rootNetworkUuid);
}

/**
Expand Down Expand Up @@ -895,6 +929,46 @@ && hasAnyBuiltChildren(child, rootNetworkUuid, checkedChildren)) {
return false;
}

private void fillIndexedNodeInfosToInvalidate(NodeEntity nodeEntity, UUID rootNetworkUuid, InvalidateNodeInfos invalidateNodeInfos) {
// when manually invalidating a single node, if this node does not have any built children
// we need to invalidate indexed modifications up to it's last built parent, not included
if (hasAnyBuiltChildren(nodeEntity, rootNetworkUuid)) {
return;
}

// when invalidating nodes, we need to get last built parent to invalidate all its children modifications in elasticsearch
NodeEntity closestNodeWithParentHavingBuiltDescendent = getSubTreeToInvalidateIndexedModifications(nodeEntity.getIdNode(), rootNetworkUuid);
fillIndexedNodeInfosToInvalidate(closestNodeWithParentHavingBuiltDescendent.getIdNode(), true, invalidateNodeInfos);
}

// For subTree
private void fillIndexedNodeTreeInfosToInvalidate(NodeEntity nodeEntity, UUID rootNetworkUuid, InvalidateNodeInfos invalidateNodeInfos) {
// when invalidating node
// we need to invalidate indexed modifications up to it's last built parent, not included
boolean isNodeBuilt = self.getNodeBuildStatus(nodeEntity.getIdNode(), rootNetworkUuid).isBuilt();
if (!isNodeBuilt && !hasAnyBuiltChildren(getNodeEntity(nodeEntity.getIdNode()), rootNetworkUuid)) {
return;
}

// TODO check invalidateOnlyChildrenBuildStatus
if (isNodeBuilt) {
fillIndexedNodeInfosToInvalidate(nodeEntity.getIdNode(), false, invalidateNodeInfos);
} else {
NodeEntity closestNodeWithParentHavingBuiltDescendent = getSubTreeToInvalidateIndexedModifications(nodeEntity.getIdNode(), rootNetworkUuid);
fillIndexedNodeInfosToInvalidate(closestNodeWithParentHavingBuiltDescendent.getIdNode(), true, invalidateNodeInfos);
}
}

private InvalidateNodeInfos invalidateChildrenNodes(UUID nodeUuid, UUID rootNetworkUuid) {
InvalidateNodeInfos invalidateNodeInfos = new InvalidateNodeInfos();
nodesRepository.findAllByParentNodeIdNode(nodeUuid)
.forEach(child -> {
invalidateNodeInfos.add(rootNetworkNodeInfoService.invalidateRootNetworkNode(child.getIdNode(), rootNetworkUuid, true));
invalidateNodeInfos.add(invalidateChildrenNodes(child.getIdNode(), rootNetworkUuid));
});
return invalidateNodeInfos;
}

private void invalidateChildrenBuildStatus(UUID nodeUuid, UUID rootNetworkUuid, List<UUID> changedNodes, InvalidateNodeInfos invalidateNodeInfos,
boolean deleteVoltageInitResults) {
nodesRepository.findAllByParentNodeIdNode(nodeUuid)
Expand All @@ -906,7 +980,6 @@ private void invalidateChildrenBuildStatus(UUID nodeUuid, UUID rootNetworkUuid,

@Transactional
public void updateNodeBuildStatus(UUID nodeUuid, UUID rootNetworkUuid, NodeBuildStatus nodeBuildStatus) {
List<UUID> changedNodes = new ArrayList<>();
UUID studyId = self.getStudyUuidForNodeId(nodeUuid);
RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = rootNetworkNodeInfoService.getRootNetworkNodeInfo(nodeUuid, rootNetworkUuid).orElseThrow(() -> new StudyException(ROOT_NETWORK_NOT_FOUND));
NodeEntity nodeEntity = getNodeEntity(nodeUuid);
Expand All @@ -932,8 +1005,7 @@ public void updateNodeBuildStatus(UUID nodeUuid, UUID rootNetworkUuid, NodeBuild
}

rootNetworkNodeInfoEntity.setNodeBuildStatus(newNodeStatus);
changedNodes.add(nodeUuid);
notificationService.emitNodeBuildStatusUpdated(studyId, changedNodes, rootNetworkUuid);
notificationService.emitNodeBuildStatusUpdated(studyId, List.of(nodeUuid), rootNetworkUuid);
}

@Transactional(readOnly = true)
Expand Down Expand Up @@ -1034,13 +1106,13 @@ public long countBuiltNodes(UUID studyUuid, UUID rootNetworkUuid) {
return nodes.stream().filter(n -> self.getNodeBuildStatus(n.getIdNode(), rootNetworkUuid).isBuilt()).count();
}

private void fillIndexedModificationsInfosToInvalidate(UUID parentNodeUuid, boolean includeParentNode, InvalidateNodeInfos invalidateNodeInfos) {
private void fillIndexedNodeInfosToInvalidate(UUID parentNodeUuid, boolean includeParentNode, InvalidateNodeInfos invalidateNodeInfos) {
List<UUID> nodesToInvalidate = new ArrayList<>();
if (includeParentNode) {
nodesToInvalidate.add(parentNodeUuid);
}
nodesToInvalidate.addAll(getChildren(parentNodeUuid));
invalidateNodeInfos.addGroupUuid(
invalidateNodeInfos.addGroupUuids(
networkModificationNodeInfoRepository.findAllById(nodesToInvalidate).stream()
.map(NetworkModificationNodeInfoEntity::getModificationGroupUuid).toList()
);
Expand Down
Loading