Skip to content
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
ced0789
wip
EtienneLt Mar 10, 2026
1dbba5c
Merge branch 'main' into add-endpoint-for-allcomputationstatus
EtienneLt Mar 11, 2026
ee6e147
checkstyle
EtienneLt Mar 11, 2026
7844f6c
fix
EtienneLt Mar 11, 2026
7b76622
add test
EtienneLt Mar 11, 2026
0f66ee5
Merge branch 'main' of https://github.com/powsybl/powsybl-study-serve…
Mar 20, 2026
0311368
Merge branch 'main' of https://github.com/powsybl/powsybl-study-serve…
Apr 8, 2026
d95f20d
Merge branch 'main' into add-endpoint-for-allcomputationstatus
EtienneLt Apr 14, 2026
6746ab9
set map
EtienneLt Apr 15, 2026
82ff0d7
transform allcomputing to map
EtienneLt Apr 15, 2026
c1891e7
fix
EtienneLt Apr 15, 2026
c2dd3ad
Merge branch 'main' into add-endpoint-for-allcomputationstatus
EtienneLt Apr 21, 2026
f7ac6e1
review
EtienneLt Apr 22, 2026
d8a61ad
Review
Apr 22, 2026
631543c
clean
EtienneLt Apr 22, 2026
4d1a9c3
when node is unbuit notify all computation status at once
EtienneLt Apr 27, 2026
84c1b6c
fix tests
EtienneLt Apr 28, 2026
d6da182
fix
EtienneLt Apr 28, 2026
085b8c9
Merge branch 'main' into add-endpoint-for-allcomputationstatus
EtienneLt Apr 28, 2026
01a3b94
clean
EtienneLt Apr 28, 2026
5bcf505
Merge branch 'main' of https://github.com/powsybl/powsybl-study-serve…
May 12, 2026
dc311fd
Merge branch 'main' into add-endpoint-for-allcomputationstatus
EtienneLt May 13, 2026
37e80e6
add notification all status without lf
EtienneLt May 26, 2026
ae7342c
clean and fix
EtienneLt May 26, 2026
24fac75
add comment
EtienneLt May 27, 2026
ac0bd70
Merge branch 'main' into add-endpoint-for-allcomputationstatus
EtienneLt May 27, 2026
7482d46
Merge branch 'main' into add-endpoint-for-allcomputationstatus
EtienneLt Jun 12, 2026
f66aa34
Merge branch 'main' into add-endpoint-for-allcomputationstatus
EtienneLt Jun 17, 2026
8bbaa61
Review
Jun 19, 2026
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 @@ -22,9 +22,6 @@
import org.gridsuite.study.server.StudyApi;
import org.gridsuite.study.server.dto.*;
import org.gridsuite.study.server.dto.computation.LoadFlowComputationInfos;
import org.gridsuite.study.server.dto.dynamicmargincalculation.DynamicMarginCalculationStatus;
import org.gridsuite.study.server.dto.dynamicsecurityanalysis.DynamicSecurityAnalysisStatus;
import org.gridsuite.study.server.dto.dynamicsimulation.DynamicSimulationStatus;
import org.gridsuite.study.server.dto.dynamicsimulation.event.EventInfos;
import org.gridsuite.study.server.dto.elasticsearch.EquipmentInfos;
import org.gridsuite.study.server.dto.modification.ModificationType;
Expand Down Expand Up @@ -63,7 +60,7 @@
import java.util.*;

import static org.gridsuite.study.server.StudyConstants.*;
import static org.gridsuite.study.server.dto.ComputationType.LOAD_FLOW;
import static org.gridsuite.study.server.dto.ComputationType.*;
import static org.gridsuite.study.server.error.StudyBusinessErrorCode.MOVE_NETWORK_MODIFICATION_FORBIDDEN;

/**
Expand Down Expand Up @@ -804,9 +801,8 @@ public ResponseEntity<String> getLoadflowResult(@Parameter(description = "study
public ResponseEntity<String> getLoadFlowStatus(@Parameter(description = "Study UUID") @PathVariable("studyUuid") UUID studyUuid,
@Parameter(description = "rootNetworkUuid") @PathVariable("rootNetworkUuid") UUID rootNetworkUuid,
@Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) {
LoadFlowStatus result = rootNetworkNodeInfoService.getLoadFlowStatus(nodeUuid, rootNetworkUuid);
return result != null ? ResponseEntity.ok().body(result.name()) :
ResponseEntity.noContent().build();
String result = rootNetworkNodeInfoService.getLoadFlowStatus(nodeUuid, rootNetworkUuid);
return result != null ? ResponseEntity.ok().body(result) : ResponseEntity.noContent().build();
}

@GetMapping(value = "/studies/{studyUuid}/root-networks/{rootNetworkUuid}/nodes/{nodeUuid}/loadflow/computation-infos")
Expand Down Expand Up @@ -1263,9 +1259,8 @@ public ResponseEntity<String> generateNetworkAreaDiagram(
public ResponseEntity<String> getSecurityAnalysisStatus(@Parameter(description = "Study UUID") @PathVariable("studyUuid") UUID studyUuid,
@Parameter(description = "rootNetworkUuid") @PathVariable("rootNetworkUuid") UUID rootNetworkUuid,
@Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) {
SecurityAnalysisStatus status = rootNetworkNodeInfoService.getSecurityAnalysisStatus(nodeUuid, rootNetworkUuid);
return status != null ? ResponseEntity.ok().body(status.name()) :
ResponseEntity.noContent().build();
String status = rootNetworkNodeInfoService.getSecurityAnalysisStatus(nodeUuid, rootNetworkUuid);
return status != null ? ResponseEntity.ok().body(status) : ResponseEntity.noContent().build();
}

@PutMapping(value = "/studies/{studyUuid}/root-networks/{rootNetworkUuid}/nodes/{nodeUuid}/security-analysis/stop")
Expand Down Expand Up @@ -1995,9 +1990,8 @@ public ResponseEntity<List<TimelineEventInfos>> getDynamicSimulationTimelineResu
public ResponseEntity<String> getDynamicSimulationStatus(@Parameter(description = "study UUID") @PathVariable("studyUuid") UUID studyUuid,
@Parameter(description = "rootNetworkUuid") @PathVariable("rootNetworkUuid") UUID rootNetworkUuid,
@Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) {
DynamicSimulationStatus result = rootNetworkNodeInfoService.getDynamicSimulationStatus(nodeUuid, rootNetworkUuid);
return result != null ? ResponseEntity.ok().body(result.name()) :
ResponseEntity.noContent().build();
String result = rootNetworkNodeInfoService.getDynamicSimulationStatus(nodeUuid, rootNetworkUuid);
return result != null ? ResponseEntity.ok().body(result) : ResponseEntity.noContent().build();
}

// --- Dynamic Simulation Endpoints END --- //
Expand Down Expand Up @@ -2046,9 +2040,8 @@ public ResponseEntity<Void> runDynamicSecurityAnalysis(@Parameter(description =
public ResponseEntity<String> getDynamicSecurityAnalysisStatus(@Parameter(description = "study UUID") @PathVariable("studyUuid") UUID studyUuid,
@Parameter(description = "root network id") @PathVariable("rootNetworkUuid") UUID rootNetworkUuid,
@Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) {
DynamicSecurityAnalysisStatus result = rootNetworkNodeInfoService.getDynamicSecurityAnalysisStatus(nodeUuid, rootNetworkUuid);
return result != null ? ResponseEntity.ok().body(result.name()) :
ResponseEntity.noContent().build();
String result = rootNetworkNodeInfoService.getDynamicSecurityAnalysisStatus(nodeUuid, rootNetworkUuid);
return result != null ? ResponseEntity.ok().body(result) : ResponseEntity.noContent().build();
}

// --- Dynamic Security Analysis Endpoints END --- //
Expand Down Expand Up @@ -2099,9 +2092,8 @@ public ResponseEntity<Void> runDynamicMarginCalculation(@Parameter(description =
public ResponseEntity<String> getDynamicMarginCalculationStatus(@Parameter(description = "study UUID") @PathVariable("studyUuid") UUID studyUuid,
@Parameter(description = "root network id") @PathVariable("rootNetworkUuid") UUID rootNetworkUuid,
@Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) {
DynamicMarginCalculationStatus result = rootNetworkNodeInfoService.getDynamicMarginCalculationStatus(nodeUuid, rootNetworkUuid);
return result != null ? ResponseEntity.ok().body(result.name()) :
ResponseEntity.noContent().build();
String result = rootNetworkNodeInfoService.getDynamicMarginCalculationStatus(nodeUuid, rootNetworkUuid);
return result != null ? ResponseEntity.ok().body(result) : ResponseEntity.noContent().build();
}

// --- Dynamic Margin Calculation Endpoints END --- //
Expand Down Expand Up @@ -2518,4 +2510,13 @@ public ResponseEntity<Void> setPccMinParameters(
@RequestHeader(HEADER_USER_ID) String userId) {
return studyService.setPccMinParameters(studyUuid, pccMinParametersInfos, userId) ? ResponseEntity.noContent().build() : ResponseEntity.ok().build();
}

@GetMapping(value = "/studies/{studyUuid}/root-networks/{rootNetworkUuid}/nodes/{nodeUuid}/computations/status")
@Operation(summary = "Get all computation status on study")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "all status are returned")})
public ResponseEntity<Map<ComputationType, String>> getAllComputationsStatus(@Parameter(description = "Study UUID") @PathVariable("studyUuid") UUID studyUuid,
@Parameter(description = "Root network UUID") @PathVariable("rootNetworkUuid") UUID rootNetworkUuid,
@Parameter(description = "Node UUID") @PathVariable("nodeUuid") UUID nodeUuid) {
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(studyService.getAllComputationsStatus(studyUuid, rootNetworkUuid, nodeUuid));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ public class NotificationService {
public static final String HEADER_CLIENT_ID = "clientId";
public static final String NETWORK_EXPORT_FINISHED = "networkExportFinished";

public static final String UPDATE_TYPE_ALL_COMPUTATION_STATUS = "all_computation_status";
public static final String UPDATE_TYPE_ALL_COMPUTATION_STATUS_WITHOUT_LOADFLOW = "all_computation_status_without_loadflow";
public static final String UPDATE_TYPE_BUILD_CANCELLED = "buildCancelled";
public static final String UPDATE_TYPE_BUILD_COMPLETED = "buildCompleted";
public static final String UPDATE_TYPE_BUILD_FAILED = "buildFailed";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
import org.gridsuite.study.server.dto.IdentifiableInfos;
import org.gridsuite.study.server.dto.InfoTypeParameters;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -792,8 +792,9 @@ public String getPccMinResult(UUID nodeUuid, UUID rootNetworkUuid, String filter
* GET COMPUTATION STATUS *
**************************/
@Transactional(readOnly = true)
public LoadFlowStatus getLoadFlowStatus(UUID nodeUuid, UUID rootNetworkUuid) {
return getBasicLoadFlowStatus(nodeUuid, rootNetworkUuid);
public String getLoadFlowStatus(UUID nodeUuid, UUID rootNetworkUuid) {
LoadFlowStatus status = getBasicLoadFlowStatus(nodeUuid, rootNetworkUuid);
return status == null ? null : status.name();
}

@Transactional(readOnly = true)
Expand Down Expand Up @@ -834,27 +835,31 @@ public String getLoadFlowModifications(UUID nodeUuid, UUID rootNetworkUuid) {
}

@Transactional(readOnly = true)
public SecurityAnalysisStatus getSecurityAnalysisStatus(UUID nodeUuid, UUID rootNetworkUuid) {
public String getSecurityAnalysisStatus(UUID nodeUuid, UUID rootNetworkUuid) {
UUID resultUuid = getComputationResultUuid(nodeUuid, rootNetworkUuid, SECURITY_ANALYSIS);
return securityAnalysisService.getSecurityAnalysisStatus(resultUuid);
SecurityAnalysisStatus status = securityAnalysisService.getSecurityAnalysisStatus(resultUuid);
return status == null ? null : status.name();
}

@Transactional(readOnly = true)
public DynamicSimulationStatus getDynamicSimulationStatus(UUID nodeUuid, UUID rootNetworkUuid) {
public String getDynamicSimulationStatus(UUID nodeUuid, UUID rootNetworkUuid) {
UUID resultUuid = getComputationResultUuid(nodeUuid, rootNetworkUuid, DYNAMIC_SIMULATION);
return dynamicSimulationService.getStatus(resultUuid);
DynamicSimulationStatus status = dynamicSimulationService.getStatus(resultUuid);
return status == null ? null : status.name();
}

@Transactional(readOnly = true)
public DynamicSecurityAnalysisStatus getDynamicSecurityAnalysisStatus(UUID nodeUuid, UUID rootNetworkUuid) {
public String getDynamicSecurityAnalysisStatus(UUID nodeUuid, UUID rootNetworkUuid) {
UUID resultUuid = getComputationResultUuid(nodeUuid, rootNetworkUuid, DYNAMIC_SECURITY_ANALYSIS);
return dynamicSecurityAnalysisService.getStatus(resultUuid);
DynamicSecurityAnalysisStatus status = dynamicSecurityAnalysisService.getStatus(resultUuid);
return status == null ? null : status.name();
}

@Transactional(readOnly = true)
public DynamicMarginCalculationStatus getDynamicMarginCalculationStatus(UUID nodeUuid, UUID rootNetworkUuid) {
public String getDynamicMarginCalculationStatus(UUID nodeUuid, UUID rootNetworkUuid) {
UUID resultUuid = getComputationResultUuid(nodeUuid, rootNetworkUuid, DYNAMIC_MARGIN_CALCULATION);
return dynamicMarginCalculationService.getStatus(resultUuid);
DynamicMarginCalculationStatus status = dynamicMarginCalculationService.getStatus(resultUuid);
return status == null ? null : status.name();
}

public String getSensitivityAnalysisStatus(UUID nodeUuid, UUID rootNetworkUuid) {
Expand Down
39 changes: 25 additions & 14 deletions src/main/java/org/gridsuite/study/server/service/StudyService.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import org.gridsuite.study.server.service.dynamicsimulation.DynamicSimulationEventService;
import org.gridsuite.study.server.service.dynamicsimulation.DynamicSimulationService;
import org.gridsuite.study.server.service.shortcircuit.ShortCircuitService;
import org.gridsuite.study.server.service.shortcircuit.ShortcircuitAnalysisType;
import org.gridsuite.study.server.utils.ElementType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -3019,8 +3020,8 @@ private UUID handleDynamicSecurityAnalysisRequest(StudyEntity studyEntity, UUID
throw new StudyException(NOT_ALLOWED, "Load flow must run successfully before running dynamic security analysis");
}

DynamicSimulationStatus dsStatus = rootNetworkNodeInfoService.getDynamicSimulationStatus(nodeUuid, rootNetworkUuid);
if (DynamicSimulationStatus.CONVERGED != dsStatus) {
String dsStatus = rootNetworkNodeInfoService.getDynamicSimulationStatus(nodeUuid, rootNetworkUuid);
if (!DynamicSimulationStatus.CONVERGED.name().equals(dsStatus)) {
throw new StudyException(NOT_ALLOWED, "Dynamic simulation must run successfully before running dynamic security analysis");
}

Expand Down Expand Up @@ -3236,19 +3237,12 @@ public void invalidateShortCircuitStatusOnAllNodes(UUID studyUuid) {
}

private void emitAllComputationStatusChanged(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, InvalidateNodeTreeParameters.ComputationsInvalidationMode computationsInvalidationMode) {
if (!InvalidateNodeTreeParameters.ComputationsInvalidationMode.isPreserveLoadFlowResults(computationsInvalidationMode)) {
notificationService.emitStudyChanged(studyUuid, nodeUuid, rootNetworkUuid, NotificationService.UPDATE_TYPE_LOADFLOW_STATUS);
if (InvalidateNodeTreeParameters.ComputationsInvalidationMode.isPreserveLoadFlowResults(computationsInvalidationMode)) {
// use for security node, when reruning loadflow, there is a modification due to the first lf and the node is unbuild when a modification is deleted and we want to keep the results
notificationService.emitStudyChanged(studyUuid, nodeUuid, rootNetworkUuid, NotificationService.UPDATE_TYPE_ALL_COMPUTATION_STATUS_WITHOUT_LOADFLOW);
} else {
notificationService.emitStudyChanged(studyUuid, nodeUuid, rootNetworkUuid, NotificationService.UPDATE_TYPE_ALL_COMPUTATION_STATUS);
}
notificationService.emitStudyChanged(studyUuid, nodeUuid, rootNetworkUuid, NotificationService.UPDATE_TYPE_SECURITY_ANALYSIS_STATUS);
notificationService.emitStudyChanged(studyUuid, nodeUuid, rootNetworkUuid, NotificationService.UPDATE_TYPE_SENSITIVITY_ANALYSIS_STATUS);
notificationService.emitStudyChanged(studyUuid, nodeUuid, rootNetworkUuid, NotificationService.UPDATE_TYPE_SHORT_CIRCUIT_STATUS);
notificationService.emitStudyChanged(studyUuid, nodeUuid, rootNetworkUuid, NotificationService.UPDATE_TYPE_ONE_BUS_SHORT_CIRCUIT_STATUS);
notificationService.emitStudyChanged(studyUuid, nodeUuid, rootNetworkUuid, NotificationService.UPDATE_TYPE_VOLTAGE_INIT_STATUS);
notificationService.emitStudyChanged(studyUuid, nodeUuid, rootNetworkUuid, NotificationService.UPDATE_TYPE_DYNAMIC_SIMULATION_STATUS);
notificationService.emitStudyChanged(studyUuid, nodeUuid, rootNetworkUuid, NotificationService.UPDATE_TYPE_DYNAMIC_SECURITY_ANALYSIS_STATUS);
notificationService.emitStudyChanged(studyUuid, nodeUuid, rootNetworkUuid, NotificationService.UPDATE_TYPE_DYNAMIC_MARGIN_CALCULATION_STATUS);
notificationService.emitStudyChanged(studyUuid, nodeUuid, rootNetworkUuid, NotificationService.UPDATE_TYPE_STATE_ESTIMATION_STATUS);
notificationService.emitStudyChanged(studyUuid, nodeUuid, rootNetworkUuid, NotificationService.UPDATE_TYPE_PCC_MIN_STATUS);
}

@Transactional(readOnly = true)
Expand Down Expand Up @@ -3701,6 +3695,23 @@ private List<CurrentLimitViolationInfos> getCurrentLimitViolations(UUID nodeUuid
.toList();
}

public Map<ComputationType, String> getAllComputationsStatus(@NonNull UUID studyUuid, @NonNull UUID rootNetworkUuid, @NonNull UUID nodeUuid) {
assertIsStudyExist(studyUuid);
Map<ComputationType, String> allComputationStatus = new EnumMap<>(ComputationType.class);
allComputationStatus.put(LOAD_FLOW, rootNetworkNodeInfoService.getLoadFlowStatus(nodeUuid, rootNetworkUuid));
allComputationStatus.put(SECURITY_ANALYSIS, rootNetworkNodeInfoService.getSecurityAnalysisStatus(nodeUuid, rootNetworkUuid));
allComputationStatus.put(PCC_MIN, rootNetworkNodeInfoService.getPccMinStatus(nodeUuid, rootNetworkUuid));
allComputationStatus.put(DYNAMIC_MARGIN_CALCULATION, rootNetworkNodeInfoService.getDynamicMarginCalculationStatus(nodeUuid, rootNetworkUuid));
allComputationStatus.put(DYNAMIC_SECURITY_ANALYSIS, rootNetworkNodeInfoService.getDynamicSecurityAnalysisStatus(nodeUuid, rootNetworkUuid));
allComputationStatus.put(DYNAMIC_SIMULATION, rootNetworkNodeInfoService.getDynamicSimulationStatus(nodeUuid, rootNetworkUuid));
allComputationStatus.put(STATE_ESTIMATION, rootNetworkNodeInfoService.getStateEstimationStatus(nodeUuid, rootNetworkUuid));
allComputationStatus.put(SENSITIVITY_ANALYSIS, rootNetworkNodeInfoService.getSensitivityAnalysisStatus(nodeUuid, rootNetworkUuid));
allComputationStatus.put(SHORT_CIRCUIT_ONE_BUS, rootNetworkNodeInfoService.getShortCircuitAnalysisStatus(nodeUuid, rootNetworkUuid, ShortcircuitAnalysisType.ONE_BUS));
allComputationStatus.put(SHORT_CIRCUIT, rootNetworkNodeInfoService.getShortCircuitAnalysisStatus(nodeUuid, rootNetworkUuid, ShortcircuitAnalysisType.ALL_BUSES));
allComputationStatus.put(VOLTAGE_INITIALIZATION, rootNetworkNodeInfoService.getVoltageInitStatus(nodeUuid, rootNetworkUuid));
return allComputationStatus;
}

public void invalidateStudyRootNetwork(UUID studyUuid, UUID rootNetworkUuid, String userId) {
rootNetworkService.assertIsRootNetworkInStudy(studyUuid, rootNetworkUuid);
var rootNodeUuid = networkModificationTreeService.getStudyRootNodeUuid(studyUuid);
Expand Down
Loading
Loading