Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -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;
Expand Down Expand Up @@ -882,8 +884,8 @@ public ResponseEntity<String> 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();
}

Expand Down Expand Up @@ -975,8 +977,8 @@ public ResponseEntity<String> getVoltageInitResult(@Parameter(description = "stu
public ResponseEntity<String> 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();
}

Expand Down Expand Up @@ -1815,8 +1817,8 @@ public ResponseEntity<String> getSensitivityAnalysisFilterOptions(
public ResponseEntity<String> 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();
}

Expand Down Expand Up @@ -2394,8 +2396,8 @@ public ResponseEntity<String> getStateEstimationResult(@Parameter(description =
public ResponseEntity<String> 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")
Expand All @@ -2406,8 +2408,8 @@ public ResponseEntity<String> getStateEstimationStatus(@Parameter(description =
public ResponseEntity<String> 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")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
* @author Etienne Homer <etienne.homer at rte-france.com>
*/
public enum ShortCircuitStatus {
public enum ShortCircuitAnalysisStatus {
NOT_DONE,
RUNNING,
COMPLETED
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public interface RootNetworkNodeInfoRepository extends JpaRepository<RootNetwork
@EntityGraph(attributePaths = {"rootNetwork"}, type = EntityGraph.EntityGraphType.LOAD)
List<RootNetworkNodeInfoEntity> findAllWithRootNetworkByNodeInfoId(UUID nodeInfoId);

List<RootNetworkNodeInfoEntity> findAllByNodeInfoIdInAndRootNetworkId(List<UUID> nodeInfoIds, UUID rootNetworkUuid);

Optional<RootNetworkNodeInfoEntity> findByNodeInfoIdAndRootNetworkId(UUID nodeInfoId, UUID rootNetworkUuid);

@EntityGraph(attributePaths = {"modificationsUuidsToExclude"}, type = EntityGraph.EntityGraphType.LOAD)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,19 @@
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.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.*;
Expand Down Expand Up @@ -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<UUID, LoadFlowStatus> getLoadFlowStatuses(List<UUID> 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<List<UUID>> httpEntity = new HttpEntity<>(resultUuids, headers);

Map<UUID, LoadFlowStatus> statuses = restTemplate.exchange(
path,
HttpMethod.POST,
httpEntity,
new ParameterizedTypeReference<Map<UUID, LoadFlowStatus>>() {
}
).getBody();
return statuses != null ? statuses : Map.of();
}

public void stopLoadFlow(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, UUID resultUuid, String userId) {
Expand Down Expand Up @@ -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<UUID> resultUuids) {
Map<UUID, LoadFlowStatus> loadFlowStatuses = getLoadFlowStatuses(resultUuids);
Set<LoadFlowStatus> values = new HashSet<>(loadFlowStatuses.values());
if (values.contains(LoadFlowStatus.RUNNING)) {
throw new StudyException(COMPUTATION_RUNNING);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,24 @@
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;

import java.io.UncheckedIOException;
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;
Expand Down Expand Up @@ -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<UUID, PccMinStatus> getPccMinStatuses(List<UUID> 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<List<UUID>> httpEntity = new HttpEntity<>(resultUuids, headers);
Map<UUID, PccMinStatus> statuses = restTemplate.exchange(
path,
HttpMethod.POST,
httpEntity,
new ParameterizedTypeReference<Map<UUID, PccMinStatus>>() {
}
).getBody();
return statuses != null ? statuses : Map.of();
}
Comment on lines 134 to 150
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Missing base URI in RestTemplate call causes request to fail.

Line 142 invokes restTemplate.exchange(path, ...) with only the relative path, but the pccMinServerBaseUri is not prepended. This will cause the HTTP request to fail because RestTemplate doesn't know the target server.

🐛 Proposed fix
-        return restTemplate.exchange(path, HttpMethod.POST, httpEntity, new ParameterizedTypeReference<Map<UUID, PccMinStatus>>() {
+        return restTemplate.exchange(pccMinServerBaseUri + path, HttpMethod.POST, httpEntity, new ParameterizedTypeReference<Map<UUID, PccMinStatus>>() {
         }).getBody();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
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<List<UUID>> httpEntity = new HttpEntity<>(resultUuids, headers);
return restTemplate.exchange(path, HttpMethod.POST, httpEntity, new ParameterizedTypeReference<Map<UUID, PccMinStatus>>() {
}).getBody();
}
String path = UriComponentsBuilder
.fromPath(PCC_MIN_URI + DELIMITER + "results/statuses")
.toUriString();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<List<UUID>> httpEntity = new HttpEntity<>(resultUuids, headers);
return restTemplate.exchange(pccMinServerBaseUri + path, HttpMethod.POST, httpEntity, new ParameterizedTypeReference<Map<UUID, PccMinStatus>>() {
}).getBody();
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/org/gridsuite/study/server/service/PccMinService.java` around
lines 134 - 144, The RestTemplate call is using a relative path only, so prepend
the configured base URI (pccMinServerBaseUri) to the built path before calling
restTemplate.exchange; update the code around where PCC_MIN_URI + DELIMITER +
"results/statuses" is composed (in PccMinService) to build a full URL (e.g.,
concatenate pccMinServerBaseUri and the path) and then call
restTemplate.exchange(fullUrl, HttpMethod.POST, httpEntity, new
ParameterizedTypeReference<Map<UUID, PccMinStatus>>() { }). Ensure you keep the
existing headers and HttpEntity<List<UUID>> httpEntity and return the response
body as before.


public void deletePccMinResults(List<UUID> resultsUuids) {
Expand All @@ -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<UUID> resultUuids) {
Map<UUID, PccMinStatus> pccMinStatuses = getPccMinStatuses(resultUuids);
Set<PccMinStatus> values = new HashSet<>(pccMinStatuses.values());
if (values.contains(PccMinStatus.RUNNING)) {
throw new StudyException(COMPUTATION_RUNNING);
}
}
Expand Down
Loading
Loading