diff --git a/src/main/java/org/gridsuite/study/server/controller/StudyController.java b/src/main/java/org/gridsuite/study/server/controller/StudyController.java index c015168981..f2437a90fc 100644 --- a/src/main/java/org/gridsuite/study/server/controller/StudyController.java +++ b/src/main/java/org/gridsuite/study/server/controller/StudyController.java @@ -20,6 +20,8 @@ import org.gridsuite.filter.globalfilter.GlobalFilter; import org.gridsuite.filter.utils.EquipmentType; import org.gridsuite.study.server.StudyApi; +import org.gridsuite.study.server.StudyConstants.CompositeModificationsActionType; +import org.gridsuite.study.server.StudyConstants.ModificationsActionType; import org.gridsuite.study.server.dto.*; import org.gridsuite.study.server.dto.computation.LoadFlowComputationInfos; import org.gridsuite.study.server.dto.dynamicmargincalculation.DynamicMarginCalculationStatus; @@ -882,8 +884,8 @@ public ResponseEntity getShortCircuitAnalysisStatus(@Parameter(descripti @PathVariable("rootNetworkUuid") UUID rootNetworkUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid, @Parameter(description = "type") @RequestParam(value = "type", required = false, defaultValue = "ALL_BUSES") ShortcircuitAnalysisType type) { - String result = rootNetworkNodeInfoService.getShortCircuitAnalysisStatus(nodeUuid, rootNetworkUuid, type); - return result != null ? ResponseEntity.ok().body(result) : + ShortCircuitAnalysisStatus result = rootNetworkNodeInfoService.getShortCircuitAnalysisStatus(nodeUuid, rootNetworkUuid, type); + return result != null ? ResponseEntity.ok().body(result.name()) : ResponseEntity.noContent().build(); } @@ -975,8 +977,8 @@ public ResponseEntity getVoltageInitResult(@Parameter(description = "stu public ResponseEntity getVoltageInitStatus(@Parameter(description = "Study UUID") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "rootNetworkUuid") @PathVariable("rootNetworkUuid") UUID rootNetworkUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) { - String result = rootNetworkNodeInfoService.getVoltageInitStatus(nodeUuid, rootNetworkUuid); - return result != null ? ResponseEntity.ok().body(result) : + VoltageInitStatus result = rootNetworkNodeInfoService.getVoltageInitStatus(nodeUuid, rootNetworkUuid); + return result != null ? ResponseEntity.ok().body(result.name()) : ResponseEntity.noContent().build(); } @@ -1815,8 +1817,8 @@ public ResponseEntity getSensitivityAnalysisFilterOptions( public ResponseEntity getSensitivityAnalysisStatus(@Parameter(description = "Study UUID") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "rootNetworkUuid") @PathVariable("rootNetworkUuid") UUID rootNetworkUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) { - String result = rootNetworkNodeInfoService.getSensitivityAnalysisStatus(nodeUuid, rootNetworkUuid); - return result != null ? ResponseEntity.ok().body(result) : + SensitivityAnalysisStatus result = rootNetworkNodeInfoService.getSensitivityAnalysisStatus(nodeUuid, rootNetworkUuid); + return result != null ? ResponseEntity.ok().body(result.name()) : ResponseEntity.noContent().build(); } @@ -2394,8 +2396,8 @@ public ResponseEntity getStateEstimationResult(@Parameter(description = public ResponseEntity getStateEstimationStatus(@Parameter(description = "Study UUID") @PathVariable("studyUuid") UUID studyUuid, @PathVariable("rootNetworkUuid") UUID rootNetworkUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) { - String status = rootNetworkNodeInfoService.getStateEstimationStatus(nodeUuid, rootNetworkUuid); - return status != null ? ResponseEntity.ok().body(status) : ResponseEntity.noContent().build(); + StateEstimationStatus status = rootNetworkNodeInfoService.getStateEstimationStatus(nodeUuid, rootNetworkUuid); + return status != null ? ResponseEntity.ok().body(status.name()) : ResponseEntity.noContent().build(); } @GetMapping(value = "/studies/{studyUuid}/root-networks/{rootNetworkUuid}/nodes/{nodeUuid}/pcc-min/status") @@ -2406,8 +2408,8 @@ public ResponseEntity getStateEstimationStatus(@Parameter(description = public ResponseEntity getPccMinStatus(@Parameter(description = "Study UUID") @PathVariable("studyUuid") UUID studyUuid, @PathVariable("rootNetworkUuid") UUID rootNetworkUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) { - String status = rootNetworkNodeInfoService.getPccMinStatus(nodeUuid, rootNetworkUuid); - return status != null ? ResponseEntity.ok().body(status) : ResponseEntity.noContent().build(); + PccMinStatus status = rootNetworkNodeInfoService.getPccMinStatus(nodeUuid, rootNetworkUuid); + return status != null ? ResponseEntity.ok().body(status.name()) : ResponseEntity.noContent().build(); } @PutMapping(value = "/studies/{studyUuid}/root-networks/{rootNetworkUuid}/nodes/{nodeUuid}/state-estimation/stop") diff --git a/src/main/java/org/gridsuite/study/server/dto/ShortCircuitStatus.java b/src/main/java/org/gridsuite/study/server/dto/ShortCircuitAnalysisStatus.java similarity index 91% rename from src/main/java/org/gridsuite/study/server/dto/ShortCircuitStatus.java rename to src/main/java/org/gridsuite/study/server/dto/ShortCircuitAnalysisStatus.java index 524d7a1903..7204334fb8 100644 --- a/src/main/java/org/gridsuite/study/server/dto/ShortCircuitStatus.java +++ b/src/main/java/org/gridsuite/study/server/dto/ShortCircuitAnalysisStatus.java @@ -9,7 +9,7 @@ /** * @author Etienne Homer */ -public enum ShortCircuitStatus { +public enum ShortCircuitAnalysisStatus { NOT_DONE, RUNNING, COMPLETED diff --git a/src/main/java/org/gridsuite/study/server/repository/rootnetwork/RootNetworkNodeInfoRepository.java b/src/main/java/org/gridsuite/study/server/repository/rootnetwork/RootNetworkNodeInfoRepository.java index 22a7fb7884..ea87768077 100644 --- a/src/main/java/org/gridsuite/study/server/repository/rootnetwork/RootNetworkNodeInfoRepository.java +++ b/src/main/java/org/gridsuite/study/server/repository/rootnetwork/RootNetworkNodeInfoRepository.java @@ -49,6 +49,8 @@ public interface RootNetworkNodeInfoRepository extends JpaRepository findAllWithRootNetworkByNodeInfoId(UUID nodeInfoId); + List findAllByNodeInfoIdInAndRootNetworkId(List nodeInfoIds, UUID rootNetworkUuid); + Optional findByNodeInfoIdAndRootNetworkId(UUID nodeInfoId, UUID rootNetworkUuid); @EntityGraph(attributePaths = {"modificationsUuidsToExclude"}, type = EntityGraph.EntityGraphType.LOAD) diff --git a/src/main/java/org/gridsuite/study/server/service/LoadFlowService.java b/src/main/java/org/gridsuite/study/server/service/LoadFlowService.java index 7945e6d33f..3d4c7d8510 100644 --- a/src/main/java/org/gridsuite/study/server/service/LoadFlowService.java +++ b/src/main/java/org/gridsuite/study/server/service/LoadFlowService.java @@ -20,6 +20,7 @@ import org.springframework.http.*; import org.springframework.lang.Nullable; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; @@ -27,8 +28,11 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.UUID; import static org.gridsuite.study.server.StudyConstants.*; @@ -133,14 +137,29 @@ public String getLoadFlowModifications(UUID resultUuid) { } public LoadFlowStatus getLoadFlowStatus(UUID resultUuid) { - if (resultUuid == null) { - return null; + return getLoadFlowStatuses(List.of(resultUuid)).get(resultUuid); + } + + public Map getLoadFlowStatuses(List resultUuids) { + if (CollectionUtils.isEmpty(resultUuids)) { + return Map.of(); } - UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath(DELIMITER + LOADFLOW_API_VERSION + "/results/{resultUuid}/status"); - String path = uriComponentsBuilder.buildAndExpand(resultUuid).toUriString(); + UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath(DELIMITER + LOADFLOW_API_VERSION + "/results/statuses"); + String path = uriComponentsBuilder.toUriString(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); - return restTemplate.getForObject(loadFlowServerBaseUri + path, LoadFlowStatus.class); + HttpEntity> httpEntity = new HttpEntity<>(resultUuids, headers); + + Map statuses = restTemplate.exchange( + path, + HttpMethod.POST, + httpEntity, + new ParameterizedTypeReference>() { + } + ).getBody(); + return statuses != null ? statuses : Map.of(); } public void stopLoadFlow(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, UUID resultUuid, String userId) { @@ -191,9 +210,10 @@ public void setLoadFlowServerBaseUri(String loadFlowServerBaseUri) { this.loadFlowServerBaseUri = loadFlowServerBaseUri; } - public void assertLoadFlowNotRunning(UUID resultUuid) { - LoadFlowStatus loadFlowStatus = getLoadFlowStatus(resultUuid); - if (LoadFlowStatus.RUNNING.equals(loadFlowStatus)) { + public void assertNoLoadFlowRunning(List resultUuids) { + Map loadFlowStatuses = getLoadFlowStatuses(resultUuids); + Set values = new HashSet<>(loadFlowStatuses.values()); + if (values.contains(LoadFlowStatus.RUNNING)) { throw new StudyException(COMPUTATION_RUNNING); } } diff --git a/src/main/java/org/gridsuite/study/server/service/PccMinService.java b/src/main/java/org/gridsuite/study/server/service/PccMinService.java index e9b9d8b09b..fcf0f7b451 100644 --- a/src/main/java/org/gridsuite/study/server/service/PccMinService.java +++ b/src/main/java/org/gridsuite/study/server/service/PccMinService.java @@ -18,10 +18,12 @@ import org.gridsuite.study.server.utils.ResultParameters; import org.gridsuite.study.server.utils.StudyUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.ParameterizedTypeReference; import org.springframework.data.domain.Sort; import org.springframework.http.*; import org.springframework.lang.Nullable; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; @@ -29,8 +31,11 @@ import java.net.URI; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.UUID; import org.springframework.data.domain.Pageable; @@ -118,14 +123,30 @@ public void stopPccMin(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, UUID restTemplate.put(pccMinServerBaseUri + path, Void.class); } - public String getPccMinStatus(UUID resultUuid) { - if (resultUuid == null) { - return null; + public PccMinStatus getPccMinStatus(UUID resultUuid) { + return getPccMinStatuses(List.of(resultUuid)).get(resultUuid); + } + + public Map getPccMinStatuses(List resultUuids) { + if (CollectionUtils.isEmpty(resultUuids)) { + return Map.of(); } String path = UriComponentsBuilder - .fromPath(PCC_MIN_URI + DELIMITER + "results/{resultUuid}/status") - .buildAndExpand(resultUuid).toUriString(); - return restTemplate.getForObject(pccMinServerBaseUri + path, String.class); + .fromPath(PCC_MIN_URI + DELIMITER + "results/statuses") + .toUriString(); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + HttpEntity> httpEntity = new HttpEntity<>(resultUuids, headers); + Map statuses = restTemplate.exchange( + path, + HttpMethod.POST, + httpEntity, + new ParameterizedTypeReference>() { + } + ).getBody(); + return statuses != null ? statuses : Map.of(); } public void deletePccMinResults(List resultsUuids) { @@ -142,9 +163,10 @@ public Integer getPccMinResultsCount() { return restTemplate.getForObject(pccMinServerBaseUri + path, Integer.class); } - public void assertPccMinNotRunning(UUID resultUuid) { - String status = getPccMinStatus(resultUuid); - if (PccMinStatus.RUNNING.name().equals(status)) { + public void assertNoPccMinRunning(List resultUuids) { + Map pccMinStatuses = getPccMinStatuses(resultUuids); + Set values = new HashSet<>(pccMinStatuses.values()); + if (values.contains(PccMinStatus.RUNNING)) { throw new StudyException(COMPUTATION_RUNNING); } } diff --git a/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java b/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java index 002b34bafe..d8c12cf08c 100644 --- a/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java +++ b/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java @@ -10,6 +10,7 @@ import lombok.NonNull; import org.apache.commons.lang3.StringUtils; import org.gridsuite.study.server.dto.*; +import org.gridsuite.study.server.dto.InvalidateNodeTreeParameters.ComputationsInvalidationMode; import org.gridsuite.study.server.dto.computation.LoadFlowComputationInfos; import org.gridsuite.study.server.dto.dynamicmargincalculation.DynamicMarginCalculationStatus; import org.gridsuite.study.server.dto.dynamicsecurityanalysis.DynamicSecurityAnalysisStatus; @@ -449,6 +450,10 @@ public Optional getRootNetworkNodeInfo(UUID nodeUuid, return rootNetworkNodeInfoRepository.findByNodeInfoIdAndRootNetworkId(nodeUuid, rootNetworkUuid); } + public List getRootNetworkNodeInfos(List nodeUuids, UUID rootNetworkUuid) { + return rootNetworkNodeInfoRepository.findAllByNodeInfoIdInAndRootNetworkId(nodeUuids, rootNetworkUuid); + } + private static UUID getComputationResultUuid(RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity, ComputationType computationType) { return switch (computationType) { case LOAD_FLOW -> rootNetworkNodeInfoEntity.getLoadFlowResultUuid(); @@ -470,6 +475,14 @@ public UUID getComputationResultUuid(UUID nodeUuid, UUID rootNetworkUuid, Comput return rootNetworkNodeInfoEntityOpt.map(rootNetworkNodeInfoEntity -> getComputationResultUuid(rootNetworkNodeInfoEntity, computationType)).orElse(null); } + public List getComputationResultUuids(List nodeUuids, UUID rootNetworkUuid, ComputationType computationType) { + List rootNetworkNodeInfoEntities = getRootNetworkNodeInfos(nodeUuids, rootNetworkUuid); + return rootNetworkNodeInfoEntities.stream() + .map(rootNetworkNodeInfoEntity -> getComputationResultUuid(rootNetworkNodeInfoEntity, computationType)) + .filter(Objects::nonNull) + .toList(); + } + public List getComputationResultUuids(UUID studyUuid, ComputationType computationType) { return rootNetworkNodeInfoRepository.findAllByRootNetworkStudyId(studyUuid).stream() .map(rootNetworkNodeInfoEntity -> getComputationResultUuid(rootNetworkNodeInfoEntity, computationType)) @@ -656,19 +669,21 @@ private List getReportUuids(RootNetworkNodeInfo rootNetworkNodeInfo) { .toList(); } - public void assertComputationNotRunning(UUID nodeUuid, UUID rootNetworkUuid) { - loadFlowService.assertLoadFlowNotRunning(getComputationResultUuid(nodeUuid, rootNetworkUuid, LOAD_FLOW)); - securityAnalysisService.assertSecurityAnalysisNotRunning(getComputationResultUuid(nodeUuid, rootNetworkUuid, SECURITY_ANALYSIS)); - dynamicSimulationService.assertDynamicSimulationNotRunning(getComputationResultUuid(nodeUuid, rootNetworkUuid, DYNAMIC_SIMULATION)); - dynamicSecurityAnalysisService.assertDynamicSecurityAnalysisNotRunning(getComputationResultUuid(nodeUuid, rootNetworkUuid, DYNAMIC_SECURITY_ANALYSIS)); - dynamicMarginCalculationService.assertDynamicMarginCalculationNotRunning(getComputationResultUuid(nodeUuid, rootNetworkUuid, DYNAMIC_MARGIN_CALCULATION)); - sensitivityAnalysisService.assertSensitivityAnalysisNotRunning(getComputationResultUuid(nodeUuid, rootNetworkUuid, SENSITIVITY_ANALYSIS)); - shortCircuitService.assertShortCircuitAnalysisNotRunning(getComputationResultUuid(nodeUuid, rootNetworkUuid, SHORT_CIRCUIT), getComputationResultUuid(nodeUuid, rootNetworkUuid, SHORT_CIRCUIT_ONE_BUS)); - voltageInitService.assertVoltageInitNotRunning(getComputationResultUuid(nodeUuid, rootNetworkUuid, VOLTAGE_INITIALIZATION)); - stateEstimationService.assertStateEstimationNotRunning(getComputationResultUuid(nodeUuid, rootNetworkUuid, STATE_ESTIMATION)); - pccMinService.assertPccMinNotRunning(getComputationResultUuid(nodeUuid, rootNetworkUuid, PCC_MIN)); + public void assertComputationsNotRunning(List nodeUuids, UUID rootNetworkUuid) { + loadFlowService.assertNoLoadFlowRunning(getComputationResultUuids(nodeUuids, rootNetworkUuid, LOAD_FLOW)); + securityAnalysisService.assertNoSecurityAnalysisRunning(getComputationResultUuids(nodeUuids, rootNetworkUuid, SECURITY_ANALYSIS)); + dynamicSimulationService.assertNoDynamicSimulationRunning(getComputationResultUuids(nodeUuids, rootNetworkUuid, DYNAMIC_SIMULATION)); + dynamicSecurityAnalysisService.assertNoDynamicSecurityAnalysisRunning(getComputationResultUuids(nodeUuids, rootNetworkUuid, DYNAMIC_SECURITY_ANALYSIS)); + dynamicMarginCalculationService.assertNoDynamicMarginCalculationRunning(getComputationResultUuids(nodeUuids, rootNetworkUuid, DYNAMIC_MARGIN_CALCULATION)); + sensitivityAnalysisService.assertNoSensitivityAnalysisRunning(getComputationResultUuids(nodeUuids, rootNetworkUuid, SENSITIVITY_ANALYSIS)); + shortCircuitService.assertNoShortCircuitAnalysisRunning(Stream.concat(getComputationResultUuids(nodeUuids, rootNetworkUuid, SHORT_CIRCUIT).stream(), getComputationResultUuids(nodeUuids, rootNetworkUuid, SHORT_CIRCUIT_ONE_BUS).stream()).toList()); + voltageInitService.assertNoVoltageInitRunning(getComputationResultUuids(nodeUuids, rootNetworkUuid, VOLTAGE_INITIALIZATION)); + stateEstimationService.assertNoStateEstimationRunning(getComputationResultUuids(nodeUuids, rootNetworkUuid, STATE_ESTIMATION)); + pccMinService.assertNoPccMinRunning(getComputationResultUuids(nodeUuids, rootNetworkUuid, PCC_MIN)); } + + /*************************** * GET COMPUTATION RESULTS * ***************************/ @@ -857,32 +872,32 @@ public DynamicMarginCalculationStatus getDynamicMarginCalculationStatus(UUID nod return dynamicMarginCalculationService.getStatus(resultUuid); } - public String getSensitivityAnalysisStatus(UUID nodeUuid, UUID rootNetworkUuid) { + public SensitivityAnalysisStatus getSensitivityAnalysisStatus(UUID nodeUuid, UUID rootNetworkUuid) { UUID resultUuid = getComputationResultUuid(nodeUuid, rootNetworkUuid, SENSITIVITY_ANALYSIS); return sensitivityAnalysisService.getSensitivityAnalysisStatus(resultUuid); } @Transactional(readOnly = true) - public String getShortCircuitAnalysisStatus(UUID nodeUuid, UUID rootNetworkUuid, ShortcircuitAnalysisType type) { + public ShortCircuitAnalysisStatus getShortCircuitAnalysisStatus(UUID nodeUuid, UUID rootNetworkUuid, ShortcircuitAnalysisType type) { UUID resultUuid = getComputationResultUuid(nodeUuid, rootNetworkUuid, type == ShortcircuitAnalysisType.ALL_BUSES ? SHORT_CIRCUIT : SHORT_CIRCUIT_ONE_BUS); return shortCircuitService.getShortCircuitAnalysisStatus(resultUuid); } @Transactional(readOnly = true) - public String getVoltageInitStatus(UUID nodeUuid, UUID rootNetworkUuid) { + public VoltageInitStatus getVoltageInitStatus(UUID nodeUuid, UUID rootNetworkUuid) { UUID resultUuid = getComputationResultUuid(nodeUuid, rootNetworkUuid, VOLTAGE_INITIALIZATION); return voltageInitService.getVoltageInitStatus(resultUuid); } @Transactional(readOnly = true) - public String getStateEstimationStatus(UUID nodeUuid, UUID rootNetworkUuid) { + public StateEstimationStatus getStateEstimationStatus(UUID nodeUuid, UUID rootNetworkUuid) { UUID resultUuid = getComputationResultUuid(nodeUuid, rootNetworkUuid, STATE_ESTIMATION); return stateEstimationService.getStateEstimationStatus(resultUuid); } @Transactional(readOnly = true) - public String getPccMinStatus(UUID nodeUuid, UUID rootNetworkUuid) { + public PccMinStatus getPccMinStatus(UUID nodeUuid, UUID rootNetworkUuid) { UUID resultUuid = getComputationResultUuid(nodeUuid, rootNetworkUuid, PCC_MIN); return pccMinService.getPccMinStatus(resultUuid); } diff --git a/src/main/java/org/gridsuite/study/server/service/SecurityAnalysisService.java b/src/main/java/org/gridsuite/study/server/service/SecurityAnalysisService.java index 348f36e735..7b6d0a10ce 100644 --- a/src/main/java/org/gridsuite/study/server/service/SecurityAnalysisService.java +++ b/src/main/java/org/gridsuite/study/server/service/SecurityAnalysisService.java @@ -20,19 +20,24 @@ import org.gridsuite.study.server.service.common.AbstractComputationService; import org.gridsuite.study.server.service.securityanalysis.SecurityAnalysisResultType; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.ParameterizedTypeReference; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.http.*; import org.springframework.lang.Nullable; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; import java.io.UncheckedIOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.UUID; import static org.gridsuite.study.server.StudyConstants.*; @@ -182,16 +187,29 @@ public void stopSecurityAnalysis(UUID studyUuid, UUID nodeUuid, UUID rootNetwork } public SecurityAnalysisStatus getSecurityAnalysisStatus(UUID resultUuid) { + return getSecurityAnalysisStatuses(List.of(resultUuid)).get(resultUuid); + } - if (resultUuid == null) { - return null; + public Map getSecurityAnalysisStatuses(List resultUuids) { + if (CollectionUtils.isEmpty(resultUuids)) { + return Map.of(); } - String path = UriComponentsBuilder - .fromPath(DELIMITER + SECURITY_ANALYSIS_API_VERSION + "/results/{resultUuid}/status") - .buildAndExpand(resultUuid).toUriString(); + UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath(DELIMITER + SECURITY_ANALYSIS_API_VERSION + "/results/statuses"); + String path = uriComponentsBuilder.toUriString(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); - return restTemplate.getForObject(securityAnalysisServerBaseUri + path, SecurityAnalysisStatus.class); + HttpEntity> httpEntity = new HttpEntity<>(resultUuids, headers); + + Map statuses = restTemplate.exchange( + path, + HttpMethod.POST, + httpEntity, + new ParameterizedTypeReference>() { + } + ).getBody(); + return statuses != null ? statuses : Map.of(); } public void deleteSecurityAnalysisResults(List resultsUuids) { @@ -218,9 +236,10 @@ public void invalidateSaStatus(List uuids) { } } - public void assertSecurityAnalysisNotRunning(UUID resultUuid) { - SecurityAnalysisStatus sas = getSecurityAnalysisStatus(resultUuid); - if (sas == SecurityAnalysisStatus.RUNNING) { + public void assertNoSecurityAnalysisRunning(List resultUuids) { + Map securityAnalysisStatuses = getSecurityAnalysisStatuses(resultUuids); + Set values = new HashSet<>(securityAnalysisStatuses.values()); + if (values.contains(SecurityAnalysisStatus.RUNNING)) { throw new StudyException(COMPUTATION_RUNNING); } } diff --git a/src/main/java/org/gridsuite/study/server/service/SensitivityAnalysisService.java b/src/main/java/org/gridsuite/study/server/service/SensitivityAnalysisService.java index 63cde0e41e..a9b2da4b43 100644 --- a/src/main/java/org/gridsuite/study/server/service/SensitivityAnalysisService.java +++ b/src/main/java/org/gridsuite/study/server/service/SensitivityAnalysisService.java @@ -16,9 +16,11 @@ import org.gridsuite.study.server.dto.sensianalysis.SensitivityAnalysisCsvFileInfos; import org.gridsuite.study.server.repository.StudyEntity; import org.gridsuite.study.server.service.common.AbstractComputationService; +import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.*; import org.springframework.lang.Nullable; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; @@ -26,8 +28,11 @@ import java.net.URI; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.UUID; import static org.gridsuite.study.server.StudyConstants.*; @@ -167,15 +172,30 @@ public String getSensitivityResultsFilterOptions(UUID resultUuid, String selecto return restTemplate.getForObject(uri, String.class); } - public String getSensitivityAnalysisStatus(UUID resultUuid) { - if (resultUuid == null) { - return null; + public SensitivityAnalysisStatus getSensitivityAnalysisStatus(UUID resultUuid) { + return getSensitivityAnalysisStatuses(List.of(resultUuid)).get(resultUuid); + } + + public Map getSensitivityAnalysisStatuses(List resultUuids) { + if (CollectionUtils.isEmpty(resultUuids)) { + return Map.of(); } - String path = UriComponentsBuilder.fromPath(DELIMITER + SENSITIVITY_ANALYSIS_API_VERSION + "/results/{resultUuid}/status") - .buildAndExpand(resultUuid).toUriString(); + String path = UriComponentsBuilder.fromPath(DELIMITER + SENSITIVITY_ANALYSIS_API_VERSION + "/results/statuses") + .toUriString(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + HttpEntity> httpEntity = new HttpEntity<>(resultUuids, headers); - return restTemplate.getForObject(sensitivityAnalysisServerBaseUri + path, String.class); + Map statuses = restTemplate.exchange( + path, + HttpMethod.POST, + httpEntity, + new ParameterizedTypeReference>() { + } + ).getBody(); + return statuses != null ? statuses : Map.of(); } public void stopSensitivityAnalysis(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, UUID resultUuid, String userId) { @@ -228,9 +248,10 @@ public Integer getSensitivityAnalysisResultsCount() { return restTemplate.getForObject(sensitivityAnalysisServerBaseUri + path, Integer.class); } - public void assertSensitivityAnalysisNotRunning(UUID resultUuid) { - String sas = getSensitivityAnalysisStatus(resultUuid); - if (SensitivityAnalysisStatus.RUNNING.name().equals(sas)) { + public void assertNoSensitivityAnalysisRunning(List resultUuids) { + Map sensitivityAnalysisStatuses = getSensitivityAnalysisStatuses(resultUuids); + Set values = new HashSet<>(sensitivityAnalysisStatuses.values()); + if (values.contains(SensitivityAnalysisStatus.RUNNING)) { throw new StudyException(COMPUTATION_RUNNING); } } diff --git a/src/main/java/org/gridsuite/study/server/service/StateEstimationService.java b/src/main/java/org/gridsuite/study/server/service/StateEstimationService.java index 9fe5f5ec86..0f7621c307 100644 --- a/src/main/java/org/gridsuite/study/server/service/StateEstimationService.java +++ b/src/main/java/org/gridsuite/study/server/service/StateEstimationService.java @@ -18,20 +18,25 @@ import org.gridsuite.study.server.repository.StudyEntity; import org.gridsuite.study.server.service.common.AbstractComputationService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.lang.Nullable; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; import java.io.UncheckedIOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.UUID; import static org.gridsuite.study.server.StudyConstants.*; @@ -122,14 +127,29 @@ public void stopStateEstimation(UUID studyUuid, UUID nodeUuid, UUID rootNetworkU restTemplate.put(stateEstimationServerServerBaseUri + path, Void.class); } - public String getStateEstimationStatus(UUID resultUuid) { - if (resultUuid == null) { - return null; + public StateEstimationStatus getStateEstimationStatus(UUID resultUuid) { + return getStateEstimationStatuses(List.of(resultUuid)).get(resultUuid); + } + + public Map getStateEstimationStatuses(List resultUuids) { + if (CollectionUtils.isEmpty(resultUuids)) { + return Map.of(); } String path = UriComponentsBuilder - .fromPath(DELIMITER + STATE_ESTIMATION_API_VERSION + "/results/{resultUuid}/status") - .buildAndExpand(resultUuid).toUriString(); - return restTemplate.getForObject(stateEstimationServerServerBaseUri + path, String.class); + .fromPath(DELIMITER + STATE_ESTIMATION_API_VERSION + "/results/statuses") + .toUriString(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + HttpEntity> httpEntity = new HttpEntity<>(resultUuids, headers); + Map statuses = restTemplate.exchange( + path, + HttpMethod.POST, + httpEntity, + new ParameterizedTypeReference>() { + } + ).getBody(); + return statuses != null ? statuses : Map.of(); } public void deleteStateEstimationResults(List resultsUuids) { @@ -146,9 +166,10 @@ public Integer getStateEstimationResultsCount() { return restTemplate.getForObject(stateEstimationServerServerBaseUri + path, Integer.class); } - public void assertStateEstimationNotRunning(UUID resultUuid) { - String status = getStateEstimationStatus(resultUuid); - if (StateEstimationStatus.RUNNING.name().equals(status)) { + public void assertNoStateEstimationRunning(List resultUuids) { + Map stateEstimationStatuses = getStateEstimationStatuses(resultUuids); + Set values = new HashSet<>(stateEstimationStatuses.values()); + if (values.contains(StateEstimationStatus.RUNNING)) { throw new StudyException(COMPUTATION_RUNNING); } } diff --git a/src/main/java/org/gridsuite/study/server/service/StudyService.java b/src/main/java/org/gridsuite/study/server/service/StudyService.java index 206498ff7c..a0cb619b33 100644 --- a/src/main/java/org/gridsuite/study/server/service/StudyService.java +++ b/src/main/java/org/gridsuite/study/server/service/StudyService.java @@ -12,7 +12,6 @@ import com.powsybl.loadflow.LoadFlowParameters; import io.micrometer.common.util.StringUtils; import lombok.NonNull; -import org.apache.commons.collections4.CollectionUtils; import org.gridsuite.filter.globalfilter.GlobalFilter; import org.gridsuite.filter.utils.EquipmentType; import org.gridsuite.study.server.StudyConstants; @@ -64,6 +63,7 @@ import org.springframework.lang.Nullable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; import org.springframework.web.util.UriUtils; import java.io.UncheckedIOException; @@ -1157,8 +1157,7 @@ public void assertCanBuildNode(UUID rootNetworkUuid, UUID nodeUuid) { } private void assertNoBuildNoComputationInTree(UUID rootNetworkUuid, List nodesUuids) { - // TODO modify computations endpoints to test multiple uuids - nodesUuids.forEach(uuid -> rootNetworkNodeInfoService.assertComputationNotRunning(uuid, rootNetworkUuid)); + rootNetworkNodeInfoService.assertComputationsNotRunning(nodesUuids, rootNetworkUuid); rootNetworkNodeInfoService.assertNoBuildingNode(rootNetworkUuid, nodesUuids); } diff --git a/src/main/java/org/gridsuite/study/server/service/VoltageInitService.java b/src/main/java/org/gridsuite/study/server/service/VoltageInitService.java index a2fb4275d9..6b8996f407 100644 --- a/src/main/java/org/gridsuite/study/server/service/VoltageInitService.java +++ b/src/main/java/org/gridsuite/study/server/service/VoltageInitService.java @@ -9,6 +9,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; + import org.apache.commons.lang3.StringUtils; import org.gridsuite.study.server.RemoteServicesProperties; import org.gridsuite.study.server.dto.voltageinit.ContextInfos; @@ -19,17 +20,22 @@ import org.gridsuite.study.server.dto.VoltageInitStatus; import org.gridsuite.study.server.dto.voltageinit.parameters.VoltageInitParametersInfos; import org.gridsuite.study.server.service.common.AbstractComputationService; +import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.*; import org.springframework.lang.Nullable; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; import java.io.UncheckedIOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.UUID; import static org.gridsuite.study.server.StudyConstants.*; @@ -121,8 +127,28 @@ public String getVoltageInitResult(UUID resultUuid, UUID networkUuid, String var return getVoltageInitResultOrStatus(resultUuid, "", networkUuid, variantId, globalFilters); } - public String getVoltageInitStatus(UUID resultUuid) { - return getVoltageInitResultOrStatus(resultUuid, "/status", null, null, null); + public VoltageInitStatus getVoltageInitStatus(UUID resultUuid) { + return getVoltageInitStatuses(List.of(resultUuid)).get(resultUuid); + } + + public Map getVoltageInitStatuses(List resultUuids) { + if (CollectionUtils.isEmpty(resultUuids)) { + return Map.of(); + } + String path = UriComponentsBuilder.fromPath(DELIMITER + VOLTAGE_INIT_API_VERSION + "/results/statuses").toUriString(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + HttpEntity> httpEntity = new HttpEntity<>(resultUuids, headers); + + Map statuses = restTemplate.exchange( + path, + HttpMethod.POST, + httpEntity, + new ParameterizedTypeReference>() { + } + ).getBody(); + return statuses != null ? statuses : Map.of(); } public VoltageInitParametersInfos getVoltageInitParameters(UUID parametersUuid) { @@ -228,9 +254,10 @@ public Integer getVoltageInitResultsCount() { return restTemplate.getForObject(voltageInitServerBaseUri + path, Integer.class); } - public void assertVoltageInitNotRunning(UUID resultUuid) { - String scs = getVoltageInitStatus(resultUuid); - if (VoltageInitStatus.RUNNING.name().equals(scs)) { + public void assertNoVoltageInitRunning(List resultUuids) { + Map voltageInitStatuses = getVoltageInitStatuses(resultUuids); + Set values = new HashSet<>(voltageInitStatuses.values()); + if (values.contains(VoltageInitStatus.RUNNING)) { throw new StudyException(COMPUTATION_RUNNING); } } diff --git a/src/main/java/org/gridsuite/study/server/service/client/dynamicmargincalculation/DynamicMarginCalculationClient.java b/src/main/java/org/gridsuite/study/server/service/client/dynamicmargincalculation/DynamicMarginCalculationClient.java index 919a32dbc9..16038f6c53 100644 --- a/src/main/java/org/gridsuite/study/server/service/client/dynamicmargincalculation/DynamicMarginCalculationClient.java +++ b/src/main/java/org/gridsuite/study/server/service/client/dynamicmargincalculation/DynamicMarginCalculationClient.java @@ -7,23 +7,25 @@ package org.gridsuite.study.server.service.client.dynamicmargincalculation; -import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.gridsuite.study.server.RemoteServicesProperties; import org.gridsuite.study.server.dto.ReportInfos; import org.gridsuite.study.server.dto.dynamicmargincalculation.DynamicMarginCalculationStatus; import org.gridsuite.study.server.service.StudyService; import org.gridsuite.study.server.service.client.AbstractRestClient; +import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.lang.NonNull; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.UUID; @@ -192,19 +194,32 @@ public UUID run(@NonNull String receiver, @NonNull UUID networkUuid, String vari } // --- Related result methods --- // - public DynamicMarginCalculationStatus getStatus(@NonNull UUID resultUuid) { - Objects.requireNonNull(resultUuid); + return getStatuses(List.of(resultUuid)).get(resultUuid); + } - String resultBaseUrl = buildEndPointUrl(getBaseUri(), DYNAMIC_MARGIN_CALCULATION_API_VERSION, DYNAMIC_MARGIN_CALCULATION_END_POINT_RESULT); + public Map getStatuses(List resultUuids) { + if (CollectionUtils.isEmpty(resultUuids)) { + return Map.of(); + } - String url = UriComponentsBuilder - .fromUriString(resultBaseUrl + "/{resultUuid}/status") - .buildAndExpand(resultUuid) - .toUriString(); + String endPointUrl = buildEndPointUrl(getBaseUri(), DYNAMIC_MARGIN_CALCULATION_API_VERSION, DYNAMIC_MARGIN_CALCULATION_END_POINT_RESULT); - // call dynamic-margin-calculation REST API - return getRestTemplate().getForObject(url, DynamicMarginCalculationStatus.class); + var uriComponents = UriComponentsBuilder.fromUriString(endPointUrl + "/statuses").build(); + String path = uriComponents.toUriString(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + HttpEntity> httpEntity = new HttpEntity<>(resultUuids, headers); + + Map statuses = getRestTemplate().exchange( + path, + HttpMethod.POST, + httpEntity, + new ParameterizedTypeReference>() { + } + ).getBody(); + return statuses != null ? statuses : Map.of(); } public void invalidateStatus(@NonNull List resultUuids) { diff --git a/src/main/java/org/gridsuite/study/server/service/client/dynamicsecurityanalysis/DynamicSecurityAnalysisClient.java b/src/main/java/org/gridsuite/study/server/service/client/dynamicsecurityanalysis/DynamicSecurityAnalysisClient.java index 9250732324..0f02040263 100644 --- a/src/main/java/org/gridsuite/study/server/service/client/dynamicsecurityanalysis/DynamicSecurityAnalysisClient.java +++ b/src/main/java/org/gridsuite/study/server/service/client/dynamicsecurityanalysis/DynamicSecurityAnalysisClient.java @@ -7,22 +7,25 @@ package org.gridsuite.study.server.service.client.dynamicsecurityanalysis; -import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.gridsuite.study.server.RemoteServicesProperties; import org.gridsuite.study.server.dto.ReportInfos; import org.gridsuite.study.server.dto.dynamicsecurityanalysis.DynamicSecurityAnalysisStatus; import org.gridsuite.study.server.service.StudyService; import org.gridsuite.study.server.service.client.AbstractRestClient; +import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.lang.NonNull; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.UUID; @@ -178,18 +181,33 @@ public UUID run(@NonNull String receiver, @NonNull UUID networkUuid, String vari } // --- Related result methods --- // - public DynamicSecurityAnalysisStatus getStatus(@NonNull UUID resultUuid) { - Objects.requireNonNull(resultUuid); + return getStatuses(List.of(resultUuid)).get(resultUuid); + } + + public Map getStatuses(List resultUuids) { + if (CollectionUtils.isEmpty(resultUuids)) { + return Map.of(); + } String resultBaseUrl = buildEndPointUrl(getBaseUri(), DYNAMIC_SECURITY_ANALYSIS_API_VERSION, DYNAMIC_SECURITY_ANALYSIS_END_POINT_RESULT); - String url = UriComponentsBuilder.fromUriString(resultBaseUrl + "/{resultUuid}/status") - .buildAndExpand(resultUuid) + String path = UriComponentsBuilder.fromUriString(resultBaseUrl + "/statuses") .toUriString(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + HttpEntity> httpEntity = new HttpEntity<>(resultUuids, headers); // call dynamic-security-analysis REST API - return getRestTemplate().getForObject(url, DynamicSecurityAnalysisStatus.class); + Map statuses = getRestTemplate().exchange( + path, + HttpMethod.POST, + httpEntity, + new ParameterizedTypeReference>() { + } + ).getBody(); + return statuses != null ? statuses : Map.of(); } public void invalidateStatus(@NonNull List resultUuids) { diff --git a/src/main/java/org/gridsuite/study/server/service/client/dynamicsimulation/DynamicSimulationClient.java b/src/main/java/org/gridsuite/study/server/service/client/dynamicsimulation/DynamicSimulationClient.java index 41f27ccecb..77279c019c 100644 --- a/src/main/java/org/gridsuite/study/server/service/client/dynamicsimulation/DynamicSimulationClient.java +++ b/src/main/java/org/gridsuite/study/server/service/client/dynamicsimulation/DynamicSimulationClient.java @@ -14,6 +14,7 @@ import org.springframework.lang.NonNull; import java.util.List; +import java.util.Map; import java.util.UUID; import static org.gridsuite.study.server.StudyConstants.DYNAMIC_SIMULATION_API_VERSION; @@ -56,6 +57,8 @@ UUID run(String receiver, UUID networkUuid, String variantId, ReportInfos report DynamicSimulationStatus getStatus(UUID resultUuid); + Map getStatuses(List resultUuids); + void invalidateStatus(List resultUuids); void deleteResults(List resultsUuids); diff --git a/src/main/java/org/gridsuite/study/server/service/client/dynamicsimulation/impl/DynamicSimulationClientImpl.java b/src/main/java/org/gridsuite/study/server/service/client/dynamicsimulation/impl/DynamicSimulationClientImpl.java index 226cbf9852..61a7c6f649 100644 --- a/src/main/java/org/gridsuite/study/server/service/client/dynamicsimulation/impl/DynamicSimulationClientImpl.java +++ b/src/main/java/org/gridsuite/study/server/service/client/dynamicsimulation/impl/DynamicSimulationClientImpl.java @@ -7,7 +7,6 @@ package org.gridsuite.study.server.service.client.dynamicsimulation.impl; -import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.gridsuite.study.server.RemoteServicesProperties; import org.gridsuite.study.server.dto.ReportInfos; @@ -16,15 +15,19 @@ import org.gridsuite.study.server.service.StudyService; import org.gridsuite.study.server.service.client.AbstractRestClient; import org.gridsuite.study.server.service.client.dynamicsimulation.DynamicSimulationClient; +import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.lang.NonNull; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.UUID; @@ -203,13 +206,32 @@ public UUID getTimelineResult(UUID resultUuid) { @Override public DynamicSimulationStatus getStatus(UUID resultUuid) { - Objects.requireNonNull(resultUuid); + return getStatuses(List.of(resultUuid)).get(resultUuid); + } + + @Override + public Map getStatuses(List resultUuids) { + if (CollectionUtils.isEmpty(resultUuids)) { + return Map.of(); + } + String endPointUrl = buildEndPointUrl(getBaseUri(), DYNAMIC_SIMULATION_API_VERSION, DYNAMIC_SIMULATION_END_POINT_RESULT); - var uriComponents = UriComponentsBuilder.fromUriString(endPointUrl + "/{resultUuid}/status") - .buildAndExpand(resultUuid); + var uriComponents = UriComponentsBuilder.fromUriString(endPointUrl + "/statuses").buildAndExpand(); + String path = uriComponents.toUriString(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + HttpEntity> httpEntity = new HttpEntity<>(resultUuids, headers); - return getRestTemplate().getForObject(uriComponents.toUriString(), DynamicSimulationStatus.class); + Map statuses = getRestTemplate().exchange( + path, + HttpMethod.POST, + httpEntity, + new ParameterizedTypeReference>() { + } + ).getBody(); + return statuses != null ? statuses : Map.of(); } @Override diff --git a/src/main/java/org/gridsuite/study/server/service/dynamicmargincalculation/DynamicMarginCalculationService.java b/src/main/java/org/gridsuite/study/server/service/dynamicmargincalculation/DynamicMarginCalculationService.java index 5595c57401..fb84ba9d90 100644 --- a/src/main/java/org/gridsuite/study/server/service/dynamicmargincalculation/DynamicMarginCalculationService.java +++ b/src/main/java/org/gridsuite/study/server/service/dynamicmargincalculation/DynamicMarginCalculationService.java @@ -9,7 +9,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.commons.collections4.CollectionUtils; import org.gridsuite.study.server.dto.NodeReceiver; import org.gridsuite.study.server.dto.ReportInfos; import org.gridsuite.study.server.dto.dynamicmargincalculation.DynamicMarginCalculationStatus; @@ -17,11 +16,15 @@ import org.gridsuite.study.server.repository.StudyEntity; import org.gridsuite.study.server.service.client.dynamicmargincalculation.DynamicMarginCalculationClient; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import java.io.UncheckedIOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.UUID; import static org.gridsuite.study.server.error.StudyBusinessErrorCode.COMPUTATION_RUNNING; @@ -83,11 +86,15 @@ public UUID runDynamicMarginCalculation(UUID nodeUuid, UUID rootNetworkUuid, UUI } public DynamicMarginCalculationStatus getStatus(UUID resultUuid) { - return resultUuid == null ? null : dynamicMarginCalculationClient.getStatus(resultUuid); + return getDynamicMarginCalculationStatuses(List.of(resultUuid)).get(resultUuid); + } + + public Map getDynamicMarginCalculationStatuses(List resultUuids) { + return dynamicMarginCalculationClient.getStatuses(resultUuids); } public void invalidateStatus(List resultUuids) { - if (CollectionUtils.isNotEmpty(resultUuids)) { + if (!CollectionUtils.isEmpty(resultUuids)) { dynamicMarginCalculationClient.invalidateStatus(resultUuids); } } @@ -122,4 +129,12 @@ public UUID getDynamicMarginCalculationParametersUuidOrElseCreateDefault(StudyEn public String getProvider(UUID parametersUuid) { return dynamicMarginCalculationClient.getProvider(parametersUuid); } + + public void assertNoDynamicMarginCalculationRunning(List resultUuids) { + Map dynamicMarginCalculationStatuses = getDynamicMarginCalculationStatuses(resultUuids); + Set values = new HashSet<>(dynamicMarginCalculationStatuses.values()); + if (values.contains(DynamicMarginCalculationStatus.RUNNING)) { + throw new StudyException(COMPUTATION_RUNNING); + } + } } diff --git a/src/main/java/org/gridsuite/study/server/service/dynamicsecurityanalysis/DynamicSecurityAnalysisService.java b/src/main/java/org/gridsuite/study/server/service/dynamicsecurityanalysis/DynamicSecurityAnalysisService.java index 56b84d6353..06cd87e065 100644 --- a/src/main/java/org/gridsuite/study/server/service/dynamicsecurityanalysis/DynamicSecurityAnalysisService.java +++ b/src/main/java/org/gridsuite/study/server/service/dynamicsecurityanalysis/DynamicSecurityAnalysisService.java @@ -9,7 +9,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.commons.collections4.CollectionUtils; + import org.gridsuite.study.server.dto.NodeReceiver; import org.gridsuite.study.server.dto.ReportInfos; import org.gridsuite.study.server.dto.dynamicsecurityanalysis.DynamicSecurityAnalysisStatus; @@ -17,11 +17,15 @@ import org.gridsuite.study.server.repository.StudyEntity; import org.gridsuite.study.server.service.client.dynamicsecurityanalysis.DynamicSecurityAnalysisClient; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import java.io.UncheckedIOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.UUID; import static org.gridsuite.study.server.error.StudyBusinessErrorCode.COMPUTATION_RUNNING; @@ -83,11 +87,18 @@ public UUID runDynamicSecurityAnalysis(UUID nodeUuid, UUID rootNetworkUuid, UUID } public DynamicSecurityAnalysisStatus getStatus(UUID resultUuid) { - return resultUuid == null ? null : dynamicSecurityAnalysisClient.getStatus(resultUuid); + return getDynamicSecurityAnalysisStatuses(List.of(resultUuid)).get(resultUuid); + } + + public Map getDynamicSecurityAnalysisStatuses(List resultUuids) { + if (CollectionUtils.isEmpty(resultUuids)) { + return Map.of(); + } + return dynamicSecurityAnalysisClient.getStatuses(resultUuids); } public void invalidateStatus(List resultUuids) { - if (CollectionUtils.isNotEmpty(resultUuids)) { + if (!CollectionUtils.isEmpty(resultUuids)) { dynamicSecurityAnalysisClient.invalidateStatus(resultUuids); } } @@ -122,4 +133,12 @@ public UUID getDynamicSecurityAnalysisParametersUuidOrElseCreateDefault(StudyEnt public String getProvider(UUID parametersUuid) { return dynamicSecurityAnalysisClient.getProvider(parametersUuid); } + + public void assertNoDynamicSecurityAnalysisRunning(List resultUuids) { + Map dynamicSecurityAnalysisStatuses = getDynamicSecurityAnalysisStatuses(resultUuids); + Set values = new HashSet<>(dynamicSecurityAnalysisStatuses.values()); + if (values.contains(DynamicSecurityAnalysisStatus.RUNNING)) { + throw new StudyException(COMPUTATION_RUNNING); + } + } } diff --git a/src/main/java/org/gridsuite/study/server/service/dynamicsimulation/DynamicSimulationService.java b/src/main/java/org/gridsuite/study/server/service/dynamicsimulation/DynamicSimulationService.java index 3360a4066b..8ebacf121e 100644 --- a/src/main/java/org/gridsuite/study/server/service/dynamicsimulation/DynamicSimulationService.java +++ b/src/main/java/org/gridsuite/study/server/service/dynamicsimulation/DynamicSimulationService.java @@ -16,6 +16,7 @@ import org.gridsuite.study.server.repository.StudyEntity; import java.util.List; +import java.util.Map; import java.util.UUID; /** @@ -83,6 +84,13 @@ UUID runDynamicSimulation(UUID nodeUuid, UUID rootNetworkUuid, UUID networkUuid, */ DynamicSimulationStatus getStatus(UUID resultUuid); + /** + * Get the current status of the simulations + * @param resultUuids a given list of result UUIDs + * @return a map of result UUID and its corresponding dynamic simulation status + */ + Map getDynamicSimulationStatuses(List resultUuids); + /** * invalidate status of the simulation results * @param resultUuids a given list of result UUIDs @@ -117,4 +125,6 @@ UUID runDynamicSimulation(UUID nodeUuid, UUID rootNetworkUuid, UUID networkUuid, * @return a list of time-series metadata */ List getTimeSeriesMetadataList(UUID resultUuid); + + void assertNoDynamicSimulationRunning(List computationResultUuids); } diff --git a/src/main/java/org/gridsuite/study/server/service/dynamicsimulation/impl/DynamicSimulationServiceImpl.java b/src/main/java/org/gridsuite/study/server/service/dynamicsimulation/impl/DynamicSimulationServiceImpl.java index fed8ce764b..935015fb0f 100644 --- a/src/main/java/org/gridsuite/study/server/service/dynamicsimulation/impl/DynamicSimulationServiceImpl.java +++ b/src/main/java/org/gridsuite/study/server/service/dynamicsimulation/impl/DynamicSimulationServiceImpl.java @@ -12,7 +12,6 @@ import com.powsybl.timeseries.DoubleTimeSeries; import com.powsybl.timeseries.StringTimeSeries; import com.powsybl.timeseries.TimeSeries; -import org.apache.commons.collections4.CollectionUtils; import org.gridsuite.study.server.dto.NodeReceiver; import org.gridsuite.study.server.dto.ReportInfos; import org.gridsuite.study.server.dto.dynamicsimulation.DynamicSimulationStatus; @@ -26,13 +25,17 @@ import org.gridsuite.study.server.service.client.timeseries.TimeSeriesClient; import org.gridsuite.study.server.service.dynamicsimulation.DynamicSimulationService; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import java.io.UncheckedIOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.UUID; import java.util.stream.Stream; @@ -201,12 +204,17 @@ public List getTimelineResult(UUID resultUuid) { @Override public DynamicSimulationStatus getStatus(UUID resultUuid) { - return resultUuid == null ? null : dynamicSimulationClient.getStatus(resultUuid); + return getDynamicSimulationStatuses(List.of(resultUuid)).get(resultUuid); + } + + @Override + public Map getDynamicSimulationStatuses(List resultUuids) { + return dynamicSimulationClient.getStatuses(resultUuids); } @Override public void invalidateStatus(List resultUuids) { - if (CollectionUtils.isNotEmpty(resultUuids)) { + if (!CollectionUtils.isEmpty(resultUuids)) { dynamicSimulationClient.invalidateStatus(resultUuids); } } @@ -233,4 +241,12 @@ public void assertDynamicSimulationNotRunning(UUID resultUuid) { throw new StudyException(COMPUTATION_RUNNING); } } + + public void assertNoDynamicSimulationRunning(List computationResultUuids) { + Map loadFlowStatuses = getDynamicSimulationStatuses(computationResultUuids); + Set values = new HashSet<>(loadFlowStatuses.values()); + if (values.contains(DynamicSimulationStatus.RUNNING)) { + throw new StudyException(COMPUTATION_RUNNING); + } + } } diff --git a/src/main/java/org/gridsuite/study/server/service/shortcircuit/ShortCircuitService.java b/src/main/java/org/gridsuite/study/server/service/shortcircuit/ShortCircuitService.java index eed14a8c38..553c3f72ba 100644 --- a/src/main/java/org/gridsuite/study/server/service/shortcircuit/ShortCircuitService.java +++ b/src/main/java/org/gridsuite/study/server/service/shortcircuit/ShortCircuitService.java @@ -16,7 +16,7 @@ import org.gridsuite.study.server.error.StudyException; import org.gridsuite.study.server.dto.NodeReceiver; import org.gridsuite.study.server.dto.ReportInfos; -import org.gridsuite.study.server.dto.ShortCircuitStatus; +import org.gridsuite.study.server.dto.ShortCircuitAnalysisStatus; import org.gridsuite.study.server.dto.VariantInfos; import org.gridsuite.study.server.service.StudyService; import org.gridsuite.study.server.service.common.AbstractComputationService; @@ -28,6 +28,7 @@ import org.springframework.http.*; import org.springframework.lang.Nullable; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; @@ -35,9 +36,11 @@ import java.net.URI; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.UUID; import static org.gridsuite.study.server.StudyConstants.*; @@ -193,15 +196,30 @@ public String getShortCircuitAnalysisResultsPage(ResultParameters resultParamete return getShortCircuitAnalysisResource(builder.build().encode().toUri()); // need to encode because of filter JSON array } - public String getShortCircuitAnalysisStatus(UUID resultUuid) { - String resultPath = getShortCircuitAnalysisResultResourcePath(resultUuid); - if (resultPath == null) { - return null; - } + public ShortCircuitAnalysisStatus getShortCircuitAnalysisStatus(UUID resultUuid) { + return getShortCircuitAnalysisStatuses(List.of(resultUuid)).get(resultUuid); + } - UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(shortCircuitServerBaseUri + resultPath + "/status"); + public Map getShortCircuitAnalysisStatuses(List resultUuids) { + if (CollectionUtils.isEmpty(resultUuids)) { + return Map.of(); + } + String path = UriComponentsBuilder + .fromPath(DELIMITER + SHORT_CIRCUIT_API_VERSION + "/results/statuses") + .toUriString(); - return getShortCircuitAnalysisResource(builder.build().toUri()); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity> httpEntity = new HttpEntity<>(resultUuids, headers); + + Map statuses = restTemplate.exchange( + path, + HttpMethod.POST, + httpEntity, + new ParameterizedTypeReference>() { + } + ).getBody(); + return statuses != null ? statuses : Map.of(); } public String getShortCircuitAnalysisResource(URI resourcePath) { @@ -248,10 +266,10 @@ public Integer getShortCircuitResultsCount() { return restTemplate.getForObject(shortCircuitServerBaseUri + path, Integer.class); } - public void assertShortCircuitAnalysisNotRunning(UUID scsResultUuid, UUID oneBusScsResultUuid) { - String scs = getShortCircuitAnalysisStatus(scsResultUuid); - String oneBusScs = getShortCircuitAnalysisStatus(oneBusScsResultUuid); - if (ShortCircuitStatus.RUNNING.name().equals(scs) || ShortCircuitStatus.RUNNING.name().equals(oneBusScs)) { + public void assertNoShortCircuitAnalysisRunning(List resultUuids) { + Map shortCircuitStatuses = getShortCircuitAnalysisStatuses(resultUuids); + Set values = new HashSet<>(shortCircuitStatuses.values()); + if (values.contains(ShortCircuitAnalysisStatus.RUNNING)) { throw new StudyException(COMPUTATION_RUNNING); } } diff --git a/src/test/java/org/gridsuite/study/server/NetworkModificationTreeTest.java b/src/test/java/org/gridsuite/study/server/NetworkModificationTreeTest.java index 8f48228fbe..0bae96681b 100644 --- a/src/test/java/org/gridsuite/study/server/NetworkModificationTreeTest.java +++ b/src/test/java/org/gridsuite/study/server/NetworkModificationTreeTest.java @@ -449,7 +449,7 @@ private void assertForbiddenNodeInsertions(UUID studyId, String userId, NetworkModificationNode security1, NetworkModificationNode security2) throws Exception { // Construction node cannot be inserted before a security node - doNothing().when(rootNetworkNodeInfoService).assertComputationNotRunning(any(), any()); + doNothing().when(rootNetworkNodeInfoService).assertComputationsNotRunning(any(), any()); mockMvc.perform(post("/v1/studies/{studyUuid}/tree/nodes?nodeToCutUuid={nodeUuid}&referenceNodeUuid={referenceNodeUuid}&insertMode={insertMode}", studyId, construction2.getId(), security1.getId(), InsertMode.BEFORE) .header(USER_ID_HEADER, userId)) @@ -637,7 +637,7 @@ void testNodeStashAndRestore() throws Exception { assertEquals("not built node", networkModificationNode.getDescription()); //stash 1 node and do the checks - doNothing().when(rootNetworkNodeInfoService).assertComputationNotRunning(any(), any()); + doNothing().when(rootNetworkNodeInfoService).assertComputationsNotRunning(any(), any()); stashNode(root.getStudyId(), children.get(0), false, Set.of(children.get(0)), userId); var stashedNode = nodeRepository.findById(children.get(0).getId()).orElseThrow(); assertTrue(stashedNode.isStashed()); @@ -1753,7 +1753,7 @@ void testNodeAliases() throws Exception { checkElementUpdatedMessageSent(root.getStudyId(), userId); // Stashing node3 (with stashChildren=true) should result in aliases no more associated to nodes node3, node4 and node5 - doNothing().when(rootNetworkNodeInfoService).assertComputationNotRunning(any(), any()); + doNothing().when(rootNetworkNodeInfoService).assertComputationsNotRunning(any(), any()); stashNode(root.getStudyId(), node3, true, Set.of(node3, node4, node5), userId); nodeAliases = objectMapper.readValue(mockMvc.perform(get("/v1/studies/{studyUuid}/node-aliases", root.getStudyId())).andExpect(status().isOk()).andReturn() .getResponse() diff --git a/src/test/java/org/gridsuite/study/server/service/client/timeseries/TimeSeriesClientTest.java b/src/test/java/org/gridsuite/study/server/service/client/timeseries/TimeSeriesClientTest.java index a421880b85..48ced1fbfe 100644 --- a/src/test/java/org/gridsuite/study/server/service/client/timeseries/TimeSeriesClientTest.java +++ b/src/test/java/org/gridsuite/study/server/service/client/timeseries/TimeSeriesClientTest.java @@ -20,8 +20,6 @@ import mockwebserver3.junit5.internal.MockWebServerExtension; import okhttp3.Headers; import okhttp3.HttpUrl; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.collections4.ListUtils; import org.gridsuite.study.server.ContextConfigurationWithTestChannel; import org.gridsuite.study.server.RemoteServicesProperties; import org.gridsuite.study.server.dto.timeseries.rest.TimeSeriesGroupRest; @@ -38,11 +36,11 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; +import org.springframework.util.CollectionUtils; import org.springframework.web.client.RestTemplate; import java.util.*; -import static org.apache.commons.collections4.CollectionUtils.emptyIfNull; import static org.assertj.core.api.Assertions.assertThat; import static org.gridsuite.study.server.service.client.timeseries.TimeSeriesClient.API_VERSION; import static org.gridsuite.study.server.service.client.timeseries.TimeSeriesClient.TIME_SERIES_END_POINT; @@ -92,7 +90,7 @@ public MockResponse dispatch(@NotNull RecordedRequest recordedRequest) { String method = recordedRequest.getMethod(); MockResponse response = new MockResponse(HttpStatus.NOT_FOUND.value()); - List pathSegments = ListUtils.emptyIfNull(recordedRequest.getRequestUrl().pathSegments()); + List pathSegments = Optional.ofNullable(recordedRequest.getRequestUrl().pathSegments()).orElse(List.of()); // timeseries-group/{groupUuid}/xxx if ("GET".equals(method) && path.matches(TIME_SERIES_BASE_URL + "/.*")) { @@ -111,7 +109,7 @@ public MockResponse dispatch(@NotNull RecordedRequest recordedRequest) { } } else { // take {groupUuid} at the last - String groupUuid = emptyIfNull(recordedRequest.getRequestUrl().pathSegments()).stream().reduce((first, second) -> second).orElse(""); + String groupUuid = Optional.ofNullable(recordedRequest.getRequestUrl().pathSegments()).orElse(List.of()).stream().reduce((first, second) -> second).orElse(""); String timeSeriesNames = recordedRequest.getRequestUrl().queryParameter("timeSeriesNames"); LOGGER.info("sent timeSeriesNames = {}", timeSeriesNames); List> timeseries; diff --git a/src/test/java/org/gridsuite/study/server/studycontroller/NodeControllerTest.java b/src/test/java/org/gridsuite/study/server/studycontroller/NodeControllerTest.java index b0744d0959..806d2c6bdd 100644 --- a/src/test/java/org/gridsuite/study/server/studycontroller/NodeControllerTest.java +++ b/src/test/java/org/gridsuite/study/server/studycontroller/NodeControllerTest.java @@ -372,7 +372,7 @@ private void cutAndPasteNode(UUID studyUuid, NetworkModificationNode nodeToCopy, boolean wasBuilt = rootNetworkNodeInfoService.getRootNetworkNodeInfo(nodeToCopy.getId(), studyTestUtils.getOneRootNetworkUuid(studyUuid)).get().getNodeBuildStatus().toDto().isBuilt(); UUID deleteModificationIndexStub = wireMockStubs.stubNetworkModificationDeleteIndex(); output.receive(TIMEOUT, studyUpdateDestination); - doNothing().when(rootNetworkNodeInfoService).assertComputationNotRunning(any(), any()); + doNothing().when(rootNetworkNodeInfoService).assertComputationsNotRunning(any(), any()); mockMvc.perform(post(STUDIES_URL + "/{studyUuid}/tree/nodes?nodeToCutUuid={nodeUuid}&referenceNodeUuid={referenceNodeUuid}&insertMode={insertMode}", studyUuid, nodeToCopy.getId(), referenceNodeUuid, insertMode)