Skip to content

Commit e499911

Browse files
SlimaneAmarSlimane AMAR
andauthored
Block node build (#792)
Co-authored-by: Slimane AMAR <[email protected]>
1 parent 2090a19 commit e499911

19 files changed

+483
-339
lines changed

src/main/java/org/gridsuite/study/server/controller/StudyController.java

Lines changed: 37 additions & 8 deletions
Large diffs are not rendered by default.

src/main/java/org/gridsuite/study/server/dto/InvalidateNodeTreeParameters.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,17 @@
1616
@Builder
1717
public record InvalidateNodeTreeParameters(
1818
InvalidationMode invalidationMode,
19+
boolean withBlockedNodeBuild,
1920
ComputationsInvalidationMode computationsInvalidationMode // Only for the first node (root node)
2021
) {
21-
public static InvalidateNodeTreeParameters ALL = new InvalidateNodeTreeParameters(InvalidationMode.ALL, ComputationsInvalidationMode.ALL);
22-
public static InvalidateNodeTreeParameters ONLY_CHILDREN = new InvalidateNodeTreeParameters(InvalidationMode.ONLY_CHILDREN, ComputationsInvalidationMode.ALL);
23-
public static InvalidateNodeTreeParameters ONLY_CHILDREN_BUILD_STATUS = new InvalidateNodeTreeParameters(InvalidationMode.ONLY_CHILDREN_BUILD_STATUS, ComputationsInvalidationMode.ALL);
22+
public static InvalidateNodeTreeParameters ALL = new InvalidateNodeTreeParameters(InvalidationMode.ALL, false, ComputationsInvalidationMode.ALL);
23+
public static InvalidateNodeTreeParameters ALL_WITH_BLOCK_NODES = new InvalidateNodeTreeParameters(InvalidationMode.ALL, true, ComputationsInvalidationMode.ALL);
24+
public static InvalidateNodeTreeParameters ONLY_CHILDREN = new InvalidateNodeTreeParameters(InvalidationMode.ONLY_CHILDREN, false, ComputationsInvalidationMode.ALL);
25+
public static InvalidateNodeTreeParameters ONLY_CHILDREN_BUILD_STATUS = new InvalidateNodeTreeParameters(InvalidationMode.ONLY_CHILDREN_BUILD_STATUS, false, ComputationsInvalidationMode.ALL);
2426
public static InvalidateNodeTreeParameters DEFAULT = ALL;
2527

2628
public enum InvalidationMode {
27-
ALL, ONLY_CHILDREN, ONLY_CHILDREN_BUILD_STATUS;
29+
ALL, ONLY_CHILDREN, ONLY_CHILDREN_BUILD_STATUS
2830
}
2931

3032
public enum ComputationsInvalidationMode {
@@ -45,7 +47,7 @@ public boolean isOnlyChildren() {
4547
return invalidationMode == InvalidationMode.ONLY_CHILDREN;
4648
}
4749

48-
public boolean isOnlyChildrenBuildStatusMode() {
50+
public boolean isOnlyChildrenBuildStatus() {
4951
return invalidationMode == InvalidationMode.ONLY_CHILDREN_BUILD_STATUS;
5052
}
5153
}

src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/RootNetworkNodeInfoEntity.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ public class RootNetworkNodeInfoEntity {
102102
@Column(name = "stateEstimationResultUuid")
103103
private UUID stateEstimationResultUuid;
104104

105+
@Column(name = "blockedBuild")
106+
private Boolean blockedBuild;
107+
105108
@Embedded
106109
@AttributeOverrides(value = {
107110
@AttributeOverride(name = "localBuildStatus", column = @Column(name = "localBuildStatus", nullable = false)),

src/main/java/org/gridsuite/study/server/repository/rootnetwork/RootNetworkNodeInfoRepository.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,12 @@ public interface RootNetworkNodeInfoRepository extends JpaRepository<RootNetwork
5454

5555
List<RootNetworkNodeInfoEntity> findAllByRootNetworkStudyIdAndLoadFlowResultUuidNotNull(UUID studyUuid);
5656

57-
@Query("select count(rnni) > 0 from RootNetworkNodeInfoEntity rnni LEFT JOIN rnni.rootNetwork rn LEFT JOIN rn.study s " +
57+
@Query("SELECT count(rnni) > 0 from RootNetworkNodeInfoEntity rnni LEFT JOIN rnni.rootNetwork rn LEFT JOIN rn.study s " +
5858
"where s.id = :studyUuid and (rnni.nodeBuildStatus.globalBuildStatus = :buildStatus or rnni.nodeBuildStatus.localBuildStatus = :buildStatus)")
5959
boolean existsByStudyUuidAndBuildStatus(UUID studyUuid, BuildStatus buildStatus);
6060

6161
List<RootNetworkNodeInfoEntity> getAllByRootNetworkIdAndNodeInfoIdIn(UUID rootNetworkUuid, List<UUID> nodesUuids);
62+
63+
@Query(value = "SELECT count(rnni) > 0 FROM RootNetworkNodeInfoEntity rnni WHERE rnni.rootNetwork.id = :rootNetworkUuid AND rnni.nodeInfo.idNode IN :nodesUuids AND rnni.blockedBuild = true ")
64+
boolean existsByNodeUuidsAndBlockedBuild(UUID rootNetworkUuid, List<UUID> nodesUuids);
6265
}

src/main/java/org/gridsuite/study/server/service/ConsumerService.java

Lines changed: 81 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,12 @@ public class ConsumerService {
4949

5050
private static final Logger LOGGER = LoggerFactory.getLogger(ConsumerService.class);
5151

52-
static final String RESULT_UUID = "resultUuid";
53-
static final String NETWORK_UUID = "networkUuid";
54-
static final String NETWORK_ID = "networkId";
55-
static final String HEADER_CASE_FORMAT = "caseFormat";
56-
static final String HEADER_CASE_NAME = "caseName";
57-
static final String HEADER_WITH_RATIO_TAP_CHANGERS = "withRatioTapChangers";
52+
private static final String RESULT_UUID = "resultUuid";
53+
private static final String NETWORK_UUID = "networkUuid";
54+
private static final String NETWORK_ID = "networkId";
55+
private static final String HEADER_CASE_FORMAT = "caseFormat";
56+
private static final String HEADER_CASE_NAME = "caseName";
57+
private static final String HEADER_WITH_RATIO_TAP_CHANGERS = "withRatioTapChangers";
5858

5959
private final ObjectMapper objectMapper;
6060

@@ -134,7 +134,7 @@ private void handleBuildResultWorkflow(UUID studyUuid, UUID nodeUuid, UUID rootN
134134
WorkflowType workflowType = WorkflowType.valueOf(workflowTypeStr);
135135
if (WorkflowType.RERUN_LOAD_FLOW.equals(workflowType)) {
136136
RerunLoadFlowInfos workflowInfos = objectMapper.readValue(URLDecoder.decode(workflowInfosStr, StandardCharsets.UTF_8), RerunLoadFlowInfos.class);
137-
studyService.sendLoadflowRequest(studyUuid, nodeUuid, rootNetworkUuid, workflowInfos.getLoadflowResultUuid(), workflowInfos.isWithRatioTapChangers(), workflowInfos.getUserId());
137+
studyService.sendLoadflowRequest(studyUuid, nodeUuid, rootNetworkUuid, workflowInfos.getLoadflowResultUuid(), workflowInfos.isWithRatioTapChangers(), false, workflowInfos.getUserId());
138138
}
139139
}
140140
}
@@ -226,54 +226,59 @@ public Consumer<Message<String>> consumeCaseImportSucceeded() {
226226
return;
227227
}
228228

229-
UUID caseUuid = receiver.getCaseUuid();
230-
UUID studyUuid = receiver.getStudyUuid();
231-
String userId = receiver.getUserId();
232-
Long startTime = receiver.getStartTime();
233-
UUID importReportUuid = receiver.getReportUuid();
234-
UUID rootNetworkUuid = receiver.getRootNetworkUuid();
235-
CaseImportAction caseImportAction = receiver.getCaseImportAction();
236-
237-
CaseInfos caseInfos = new CaseInfos(caseUuid, receiver.getOriginalCaseUuid(), caseName, caseFormat);
238-
NetworkInfos networkInfos = new NetworkInfos(networkUuid, networkId);
239-
try {
240-
switch (caseImportAction) {
241-
case STUDY_CREATION ->
242-
insertStudy(studyUuid, userId, networkInfos, caseInfos, importParameters, importReportUuid);
243-
case ROOT_NETWORK_CREATION ->
244-
studyService.createRootNetwork(studyUuid, RootNetworkInfos.builder()
245-
.id(rootNetworkUuid)
246-
.caseInfos(caseInfos)
247-
.reportUuid(importReportUuid)
248-
.networkInfos(networkInfos)
249-
.importParameters(importParameters)
250-
.build());
251-
case NETWORK_RECREATION ->
252-
studyService.updateNetwork(studyUuid, rootNetworkUuid, networkInfos, userId);
253-
case ROOT_NETWORK_MODIFICATION ->
254-
studyService.modifyRootNetwork(studyUuid, RootNetworkInfos.builder()
255-
.id(rootNetworkUuid)
256-
.networkInfos(networkInfos)
257-
.caseInfos(caseInfos)
258-
.importParameters(importParameters)
259-
.reportUuid(importReportUuid)
260-
.build(), true);
261-
}
262-
caseService.disableCaseExpiration(caseUuid);
263-
} catch (Exception e) {
264-
LOGGER.error("Error while importing case", e);
265-
} finally {
266-
// if studyEntity is already existing, we don't delete anything in the end of the process
267-
if (caseImportAction == CaseImportAction.STUDY_CREATION) {
268-
studyService.deleteStudyIfNotCreationInProgress(studyUuid);
269-
}
270-
LOGGER.trace("{} for study uuid '{}' : {} seconds", caseImportAction.getLabel(), studyUuid,
271-
TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime));
272-
}
229+
handleConsumeCaseImportSucceeded(receiver, networkUuid, networkId, caseName, caseFormat, importParameters);
273230
}
274231
};
275232
}
276233

234+
private void handleConsumeCaseImportSucceeded(CaseImportReceiver receiver, UUID networkUuid, String networkId, String caseName, String caseFormat, Map<String, String> importParameters) {
235+
UUID caseUuid = receiver.getCaseUuid();
236+
UUID studyUuid = receiver.getStudyUuid();
237+
String userId = receiver.getUserId();
238+
Long startTime = receiver.getStartTime();
239+
UUID importReportUuid = receiver.getReportUuid();
240+
UUID rootNetworkUuid = receiver.getRootNetworkUuid();
241+
CaseImportAction caseImportAction = receiver.getCaseImportAction();
242+
243+
CaseInfos caseInfos = new CaseInfos(caseUuid, receiver.getOriginalCaseUuid(), caseName, caseFormat);
244+
NetworkInfos networkInfos = new NetworkInfos(networkUuid, networkId);
245+
try {
246+
switch (caseImportAction) {
247+
case STUDY_CREATION ->
248+
insertStudy(studyUuid, userId, networkInfos, caseInfos, importParameters, importReportUuid);
249+
case ROOT_NETWORK_CREATION -> studyService.createRootNetwork(studyUuid, RootNetworkInfos.builder()
250+
.id(rootNetworkUuid)
251+
.caseInfos(caseInfos)
252+
.reportUuid(importReportUuid)
253+
.networkInfos(networkInfos)
254+
.importParameters(importParameters)
255+
.build());
256+
case NETWORK_RECREATION -> studyService.updateNetwork(studyUuid, rootNetworkUuid, networkInfos, userId);
257+
case ROOT_NETWORK_MODIFICATION -> studyService.modifyRootNetwork(studyUuid, RootNetworkInfos.builder()
258+
.id(rootNetworkUuid)
259+
.networkInfos(networkInfos)
260+
.caseInfos(caseInfos)
261+
.importParameters(importParameters)
262+
.reportUuid(importReportUuid)
263+
.build());
264+
}
265+
caseService.disableCaseExpiration(caseUuid);
266+
} catch (Exception e) {
267+
LOGGER.error("Error while importing case", e);
268+
} finally {
269+
// if studyEntity is already existing, we don't delete anything in the end of the process
270+
if (caseImportAction == CaseImportAction.STUDY_CREATION) {
271+
studyService.deleteStudyIfNotCreationInProgress(studyUuid);
272+
}
273+
if (caseImportAction == CaseImportAction.ROOT_NETWORK_MODIFICATION) {
274+
UUID rootNodeUuid = networkModificationTreeService.getStudyRootNodeUuid(studyUuid);
275+
networkModificationTreeService.invalidateBlockedBuildNodeTree(rootNetworkUuid, rootNodeUuid);
276+
}
277+
LOGGER.trace("{} for study uuid '{}' : {} seconds", caseImportAction.getLabel(), studyUuid,
278+
TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime));
279+
}
280+
}
281+
277282
private void insertStudy(UUID studyUuid, String userId, NetworkInfos networkInfos, CaseInfos caseInfos,
278283
Map<String, String> importParameters, UUID importReportUuid) {
279284
UserProfileInfos userProfileInfos = getUserProfile(userId);
@@ -521,7 +526,7 @@ public void consumeCalculationFailed(Message<String> msg, ComputationType comput
521526
}
522527
}
523528
if (!Strings.isBlank(receiver)) {
524-
NodeReceiver receiverObj;
529+
NodeReceiver receiverObj = null;
525530
try {
526531
receiverObj = objectMapper.readValue(URLDecoder.decode(receiver, StandardCharsets.UTF_8), NodeReceiver.class);
527532

@@ -530,24 +535,18 @@ public void consumeCalculationFailed(Message<String> msg, ComputationType comput
530535
// delete computation results from the databases
531536
// ==> will probably be removed soon because it prevents the front from recovering the resultId ; or 'null' parameter will be replaced by null like in VOLTAGE_INITIALIZATION
532537
rootNetworkNodeInfoService.updateComputationResultUuid(receiverObj.getNodeUuid(), receiverObj.getRootNetworkUuid(), resultUuid, computationType);
533-
534-
UUID studyUuid = networkModificationTreeService.getStudyUuidForNodeId(receiverObj.getNodeUuid());
535-
536-
if (computationType == LOAD_FLOW) {
537-
// since running loadflow impacts the network linked to the node "nodeUuid", we need to invalidate its children nodes to prevent inconsistencies
538-
studyService.invalidateNodeTree(studyUuid, receiverObj.getNodeUuid(), receiverObj.getRootNetworkUuid(), InvalidateNodeTreeParameters.ONLY_CHILDREN);
539-
}
540-
541-
// send notification for failed computation
542-
notificationService.emitStudyError(
543-
studyUuid,
544-
receiverObj.getNodeUuid(),
545-
receiverObj.getRootNetworkUuid(),
546-
computationType.getUpdateFailedType(),
547-
errorMessage,
548-
userId);
549538
} catch (JsonProcessingException e) {
550539
LOGGER.error(e.toString());
540+
} finally {
541+
if (receiverObj != null) {
542+
if (computationType == LOAD_FLOW) {
543+
networkModificationTreeService.invalidateBlockedBuildNodeTree(receiverObj.getRootNetworkUuid(), receiverObj.getNodeUuid());
544+
}
545+
546+
// send notification for failed computation
547+
UUID studyUuid = networkModificationTreeService.getStudyUuidForNodeId(receiverObj.getNodeUuid());
548+
notificationService.emitStudyError(studyUuid, receiverObj.getNodeUuid(), receiverObj.getRootNetworkUuid(), computationType.getUpdateFailedType(), errorMessage, userId);
549+
}
551550
}
552551
}
553552
}
@@ -601,22 +600,22 @@ private void consumeLoadFlowResult(Message<String> msg, boolean withRatioTapChan
601600
Optional.ofNullable(msg.getHeaders().get(RESULT_UUID, String.class))
602601
.map(UUID::fromString)
603602
.ifPresent(resultUuid -> getNodeReceiver(msg).ifPresent(receiverObj -> {
604-
LOGGER.info("{} result '{}' available for node '{}'",
605-
LOAD_FLOW.getLabel(),
606-
resultUuid,
607-
receiverObj.getNodeUuid());
608-
609-
// update DB
610-
rootNetworkNodeInfoService.updateLoadflowResultUuid(receiverObj.getNodeUuid(), receiverObj.getRootNetworkUuid(), resultUuid, withRatioTapChangers);
611-
612-
UUID studyUuid = networkModificationTreeService.getStudyUuidForNodeId(receiverObj.getNodeUuid());
603+
try {
604+
LOGGER.info("{} result '{}' available for node '{}'",
605+
LOAD_FLOW.getLabel(),
606+
resultUuid,
607+
receiverObj.getNodeUuid());
613608

614-
// since running loadflow impacts the network linked to the node "nodeUuid", we need to invalidate its children nodes to prevent inconsistencies
615-
studyService.invalidateNodeTree(studyUuid, receiverObj.getNodeUuid(), receiverObj.getRootNetworkUuid(), InvalidateNodeTreeParameters.ONLY_CHILDREN);
609+
// update DB
610+
rootNetworkNodeInfoService.updateLoadflowResultUuid(receiverObj.getNodeUuid(), receiverObj.getRootNetworkUuid(), resultUuid, withRatioTapChangers);
611+
} finally {
612+
networkModificationTreeService.invalidateBlockedBuildNodeTree(receiverObj.getRootNetworkUuid(), receiverObj.getNodeUuid());
616613

617-
// send notifications
618-
notificationService.emitStudyChanged(studyUuid, receiverObj.getNodeUuid(), receiverObj.getRootNetworkUuid(), LOAD_FLOW.getUpdateStatusType());
619-
notificationService.emitStudyChanged(studyUuid, receiverObj.getNodeUuid(), receiverObj.getRootNetworkUuid(), LOAD_FLOW.getUpdateResultType());
614+
// send notifications
615+
UUID studyUuid = networkModificationTreeService.getStudyUuidForNodeId(receiverObj.getNodeUuid());
616+
notificationService.emitStudyChanged(studyUuid, receiverObj.getNodeUuid(), receiverObj.getRootNetworkUuid(), LOAD_FLOW.getUpdateStatusType());
617+
notificationService.emitStudyChanged(studyUuid, receiverObj.getNodeUuid(), receiverObj.getRootNetworkUuid(), LOAD_FLOW.getUpdateResultType());
618+
}
620619
}));
621620
}
622621

0 commit comments

Comments
 (0)