Skip to content

Commit 489f827

Browse files
TheMaskedTurtleTristan-WorkGHdbraquart
authored
feat: allow partial loading for branches and generators (#837)
* Add partial object notion for tab view * fix * checkstyle * fix Signed-off-by: Joris Mancini <[email protected]> * fix: reduce delta Signed-off-by: Joris Mancini <[email protected]> * fix: reduce delta Signed-off-by: Joris Mancini <[email protected]> * fix: checkstyle and tests Signed-off-by: Joris Mancini <[email protected]> * refactor: rename additionalParameters to optionalParametersush Signed-off-by: Joris Mancini <[email protected]> * fix: merge error Signed-off-by: Joris Mancini <[email protected]> * test: add tests Signed-off-by: Joris Mancini <[email protected]> * typo Signed-off-by: Joris Mancini <[email protected]> --------- Signed-off-by: Joris Mancini <[email protected]> Co-authored-by: Tristan Chuine <[email protected]> Co-authored-by: dbraquart <[email protected]>
1 parent 82113e9 commit 489f827

File tree

15 files changed

+560
-44
lines changed

15 files changed

+560
-44
lines changed

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ public ResponseEntity<String> getAllMapData(
609609
@PathVariable("nodeUuid") UUID nodeUuid,
610610
@Parameter(description = "Substations id") @RequestParam(name = "substationId", required = false) List<String> substationsIds) {
611611

612-
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(studyService.getAllMapData(nodeUuid, rootNetworkUuid, substationsIds));
612+
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(studyService.getAllMapData(studyUuid, nodeUuid, rootNetworkUuid, substationsIds));
613613
}
614614

615615
@PutMapping(value = "/studies/{studyUuid}/nodes/{nodeUuid}/network-modification/{modificationUuid}")
@@ -2476,4 +2476,21 @@ public ResponseEntity<UUID> saveDiagramGridLayout(
24762476

24772477
return ResponseEntity.ok().body(studyService.saveDiagramGridLayout(studyUuid, diagramGridLayout));
24782478
}
2479+
2480+
@GetMapping(value = "/studies/{studyUuid}/spreadsheet/parameters", produces = MediaType.APPLICATION_JSON_VALUE)
2481+
@Operation(summary = "Get global parameters of the spreadsheets")
2482+
@ApiResponse(responseCode = "200", description = "Get the parameters")
2483+
@ApiResponse(responseCode = "204", description = "The study does not exist")
2484+
public ResponseEntity<SpreadsheetParameters> getSpreadsheetParameters(@PathVariable("studyUuid") final UUID studyUuid) {
2485+
return ResponseEntity.of(this.studyService.getSpreadsheetParameters(studyUuid));
2486+
}
2487+
2488+
@PutMapping(value = "/studies/{studyUuid}/spreadsheet/parameters", consumes = MediaType.APPLICATION_JSON_VALUE)
2489+
@Operation(summary = "Update global parameters of the spreadsheets")
2490+
@ApiResponse(responseCode = "204", description = "The parameters are updated")
2491+
@ApiResponse(responseCode = "404", description = "The study does not exist")
2492+
public ResponseEntity<Void> updateSpreadsheetParameters(@PathVariable("studyUuid") final UUID studyUuid,
2493+
@RequestBody final SpreadsheetParameters spreadsheetParameters) {
2494+
return (this.studyService.updateSpreadsheetParameters(studyUuid, spreadsheetParameters) ? ResponseEntity.noContent() : ResponseEntity.notFound()).build();
2495+
}
24792496
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
@Builder
1717
public class InfoTypeParameters {
1818
public static final String QUERY_PARAM_DC_POWERFACTOR = "dcPowerFactor";
19+
public static final String QUERY_PARAM_LOAD_OPERATIONAL_LIMIT_GROUPS = "loadOperationalLimitGroups";
20+
public static final String QUERY_PARAM_LOAD_REGULATING_TERMINALS = "loadRegulatingTerminals";
21+
1922
private String infoType;
2023
private Map<String, String> optionalParameters;
2124

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright (c) 2025, RTE (http://www.rte-france.com)
3+
* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this
5+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
6+
*/
7+
package org.gridsuite.study.server.dto;
8+
9+
import com.fasterxml.jackson.annotation.JsonInclude;
10+
import com.fasterxml.jackson.annotation.JsonInclude.Include;
11+
import com.fasterxml.jackson.annotation.JsonProperty;
12+
import lombok.AllArgsConstructor;
13+
import lombok.Builder;
14+
import lombok.Data;
15+
import lombok.NoArgsConstructor;
16+
import lombok.experimental.Accessors;
17+
import lombok.experimental.SuperBuilder;
18+
import lombok.extern.jackson.Jacksonized;
19+
20+
@AllArgsConstructor
21+
@NoArgsConstructor
22+
@Data
23+
@Accessors(chain = true)
24+
@Jacksonized
25+
@Builder
26+
public class SpreadsheetParameters {
27+
@JsonProperty("BRANCH")
28+
@JsonInclude(Include.NON_EMPTY)
29+
private BranchSpreadsheetParameters branch;
30+
31+
@JsonProperty("LINE")
32+
@JsonInclude(Include.NON_EMPTY)
33+
private BranchSpreadsheetParameters line;
34+
35+
@JsonProperty("TWO_WINDINGS_TRANSFORMER")
36+
@JsonInclude(Include.NON_EMPTY)
37+
private BranchSpreadsheetParameters twt;
38+
39+
@JsonProperty("GENERATOR")
40+
@JsonInclude(Include.NON_EMPTY)
41+
private GeneratorSpreadsheetParameters generator;
42+
43+
@AllArgsConstructor
44+
@NoArgsConstructor
45+
@Data
46+
@Accessors(chain = true)
47+
@Jacksonized
48+
@SuperBuilder
49+
public static class BranchSpreadsheetParameters {
50+
@JsonInclude(Include.NON_NULL)
51+
private Boolean operationalLimitsGroups;
52+
}
53+
54+
@AllArgsConstructor
55+
@NoArgsConstructor
56+
@Data
57+
@Accessors(chain = true)
58+
@Jacksonized
59+
@Builder
60+
public static class GeneratorSpreadsheetParameters {
61+
@JsonInclude(Include.NON_NULL)
62+
private Boolean regulatingTerminal;
63+
}
64+
}

src/main/java/org/gridsuite/study/server/notification/NotificationService.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ public class NotificationService {
9393
public static final String UPDATE_SPREADSHEET_NODE_ALIASES = "nodeAliasesUpdated";
9494
public static final String UPDATE_SPREADSHEET_TAB = "spreadsheetTabUpdated";
9595
public static final String UPDATE_SPREADSHEET_COLLECTION = "spreadsheetCollectionUpdated";
96+
public static final String UPDATE_SPREADSHEET_PARAMETERS = "spreadsheetParametersUpdated";
9697

9798
public static final String MODIFICATIONS_CREATING_IN_PROGRESS = "creatingInProgress";
9899
public static final String MODIFICATIONS_STASHING_IN_PROGRESS = "stashingInProgress";
@@ -201,6 +202,11 @@ public void emitSpreadsheetCollectionChanged(UUID studyUuid, UUID collectionUuid
201202
sendStudyUpdateMessage(studyUuid, UPDATE_SPREADSHEET_COLLECTION, MessageBuilder.withPayload(collectionUuid.toString()));
202203
}
203204

205+
@PostCompletion
206+
public void emitSpreadsheetParametersChange(UUID studyUuid) {
207+
sendStudyUpdateMessage(studyUuid, UPDATE_SPREADSHEET_PARAMETERS, MessageBuilder.withPayload(""));
208+
}
209+
204210
@PostCompletion
205211
public void emitNetworkVisualizationParamsChanged(UUID studyUuid) {
206212
sendStudyUpdateMessage(studyUuid, UPDATE_NETWORK_VISUALIZATION_PARAMETERS, MessageBuilder.withPayload("")
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/**
2+
* Copyright (c) 2025, RTE (http://www.rte-france.com)
3+
* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this
5+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
6+
*/
7+
package org.gridsuite.study.server.repository;
8+
9+
import jakarta.persistence.Column;
10+
import jakarta.persistence.Embeddable;
11+
import lombok.*;
12+
import lombok.Builder.Default;
13+
import org.gridsuite.study.server.dto.SpreadsheetParameters;
14+
import org.gridsuite.study.server.dto.SpreadsheetParameters.BranchSpreadsheetParameters;
15+
import org.gridsuite.study.server.dto.SpreadsheetParameters.GeneratorSpreadsheetParameters;
16+
17+
@Embeddable
18+
@NoArgsConstructor
19+
@AllArgsConstructor
20+
@Data
21+
@Builder
22+
public class SpreadsheetParametersEntity {
23+
@Column(name = "sp_load_branch_olg", nullable = false, columnDefinition = "boolean default false")
24+
@Default
25+
private boolean spreadsheetLoadBranchOperationalLimitGroup = false;
26+
27+
@Column(name = "sp_load_line_olg", nullable = false, columnDefinition = "boolean default false")
28+
@Default
29+
private boolean spreadsheetLoadLineOperationalLimitGroup = false;
30+
31+
@Column(name = "sp_load_twt_olg", nullable = false, columnDefinition = "boolean default false")
32+
@Default
33+
private boolean spreadsheetLoadTwtOperationalLimitGroup = false;
34+
35+
@Column(name = "sp_load_generator_rt", nullable = false, columnDefinition = "boolean default false")
36+
@Default
37+
private boolean spreadsheetLoadGeneratorRegulatingTerminal = false;
38+
39+
public SpreadsheetParameters toDto() {
40+
return new SpreadsheetParameters(
41+
new BranchSpreadsheetParameters(this.spreadsheetLoadBranchOperationalLimitGroup),
42+
new BranchSpreadsheetParameters(this.spreadsheetLoadLineOperationalLimitGroup),
43+
new BranchSpreadsheetParameters(this.spreadsheetLoadTwtOperationalLimitGroup),
44+
new GeneratorSpreadsheetParameters(this.spreadsheetLoadGeneratorRegulatingTerminal)
45+
);
46+
}
47+
48+
/**
49+
* @return {@code true} if the update has modified the parameters, {@code false} otherwise.
50+
*/
51+
public boolean update(@NonNull final SpreadsheetParameters dto) {
52+
boolean modified = false;
53+
final BranchSpreadsheetParameters branchParams = dto.getBranch();
54+
if (branchParams != null) {
55+
if (branchParams.getOperationalLimitsGroups() != null && this.spreadsheetLoadBranchOperationalLimitGroup != branchParams.getOperationalLimitsGroups()) {
56+
modified = true;
57+
this.spreadsheetLoadBranchOperationalLimitGroup = branchParams.getOperationalLimitsGroups();
58+
}
59+
}
60+
final BranchSpreadsheetParameters lineParams = dto.getLine();
61+
if (lineParams != null) {
62+
if (lineParams.getOperationalLimitsGroups() != null && this.spreadsheetLoadLineOperationalLimitGroup != lineParams.getOperationalLimitsGroups()) {
63+
modified = true;
64+
this.spreadsheetLoadLineOperationalLimitGroup = lineParams.getOperationalLimitsGroups();
65+
}
66+
}
67+
final BranchSpreadsheetParameters twtParams = dto.getTwt();
68+
if (twtParams != null) {
69+
if (twtParams.getOperationalLimitsGroups() != null && this.spreadsheetLoadTwtOperationalLimitGroup != twtParams.getOperationalLimitsGroups()) {
70+
modified = true;
71+
this.spreadsheetLoadTwtOperationalLimitGroup = twtParams.getOperationalLimitsGroups();
72+
}
73+
}
74+
final GeneratorSpreadsheetParameters generatorParams = dto.getGenerator();
75+
if (generatorParams != null) {
76+
if (generatorParams.getRegulatingTerminal() != null && this.spreadsheetLoadGeneratorRegulatingTerminal != generatorParams.getRegulatingTerminal()) {
77+
modified = true;
78+
this.spreadsheetLoadGeneratorRegulatingTerminal = generatorParams.getRegulatingTerminal();
79+
}
80+
}
81+
return modified;
82+
}
83+
}

src/main/java/org/gridsuite/study/server/repository/StudyEntity.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ public class StudyEntity extends AbstractManuallyAssignedIdentifierEntity<UUID>
135135
@Column(name = "mono_root", columnDefinition = "boolean default true")
136136
private boolean monoRoot;
137137

138+
@Embedded
139+
@Builder.Default
140+
private SpreadsheetParametersEntity spreadsheetParameters = new SpreadsheetParametersEntity();
141+
138142
public RootNetworkEntity getFirstRootNetwork() {
139143
return rootNetworks.get(0);
140144
}
@@ -149,4 +153,3 @@ public void deleteRootNetworks(Set<UUID> uuids) {
149153
rootNetworks.removeAll(rootNetworks.stream().filter(rn -> uuids.contains(rn.getId())).toList());
150154
}
151155
}
152-

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

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,16 @@
2525
import org.springframework.web.client.RestTemplate;
2626
import org.springframework.web.util.UriComponentsBuilder;
2727

28-
import java.util.HashMap;
2928
import java.util.List;
3029
import java.util.Map;
3130
import java.util.UUID;
3231

3332
import static org.gridsuite.study.server.StudyConstants.*;
3433
import static org.gridsuite.study.server.StudyException.Type.*;
35-
import static org.gridsuite.study.server.dto.InfoTypeParameters.QUERY_PARAM_DC_POWERFACTOR;
3634
import static org.gridsuite.study.server.utils.StudyUtils.handleHttpError;
3735

3836
@Service
3937
public class NetworkMapService {
40-
41-
static final String QUERY_PARAM_LINE_ID = "lineId";
42-
4338
private final RestTemplate restTemplate;
4439

4540
private String networkMapServerBaseUri;
@@ -50,47 +45,49 @@ public NetworkMapService(RemoteServicesProperties remoteServicesProperties, Rest
5045
this.restTemplate = restTemplate;
5146
}
5247

53-
public String getElementsInfos(UUID networkUuid, String variantId, List<String> substationsIds, String elementType, List<Double> nominalVoltages, String infoType, double dcPowerFactor) {
48+
public String getElementsInfos(UUID networkUuid,
49+
String variantId,
50+
List<String> substationsIds,
51+
String elementType,
52+
List<Double> nominalVoltages,
53+
String infoType,
54+
Map<String, String> optionalParameters) {
5455
String path = DELIMITER + NETWORK_MAP_API_VERSION + "/networks/{networkUuid}/elements";
5556
UriComponentsBuilder builder = UriComponentsBuilder.fromPath(path);
56-
5757
if (!StringUtils.isBlank(variantId)) {
5858
builder = builder.queryParam(QUERY_PARAM_VARIANT_ID, variantId);
5959
}
60-
6160
builder = builder.queryParam(QUERY_PARAM_INFO_TYPE, infoType)
6261
.queryParam(QUERY_PARAM_ELEMENT_TYPE, elementType);
63-
6462
if (nominalVoltages != null && !nominalVoltages.isEmpty()) {
6563
builder = builder.queryParam(QUERY_PARAM_NOMINAL_VOLTAGES, nominalVoltages);
6664
}
67-
InfoTypeParameters infoTypeParameters = InfoTypeParameters.builder()
68-
.optionalParameters(Map.of(QUERY_PARAM_DC_POWERFACTOR, String.valueOf(dcPowerFactor)))
69-
.build();
70-
queryParamInfoTypeParameters(infoTypeParameters, builder);
65+
queryParamInfoTypeParameters(InfoTypeParameters.builder()
66+
.optionalParameters(optionalParameters)
67+
.build(), builder);
7168
String url = builder.buildAndExpand(networkUuid).toUriString();
72-
7369
HttpHeaders headers = new HttpHeaders();
7470
headers.setContentType(MediaType.APPLICATION_JSON);
7571
HttpEntity<List<String>> httpEntity = new HttpEntity<>(substationsIds, headers);
7672
return restTemplate.postForObject(networkMapServerBaseUri + url, httpEntity, String.class);
7773
}
7874

79-
public String getElementInfos(UUID networkUuid, String variantId, String elementType, String infoType,
80-
double dcPowerFactor, String elementId) {
75+
public String getElementInfos(UUID networkUuid,
76+
String variantId,
77+
String elementType,
78+
String infoType,
79+
Map<String, String> optionalParameters,
80+
String elementId) {
8181
String path = DELIMITER + NETWORK_MAP_API_VERSION + "/networks/{networkUuid}/elements/{elementId}";
8282
UriComponentsBuilder builder = UriComponentsBuilder.fromPath(path);
8383
if (!StringUtils.isBlank(variantId)) {
8484
builder = builder.queryParam(QUERY_PARAM_VARIANT_ID, variantId);
8585
}
86-
builder = builder.queryParam(QUERY_PARAM_ELEMENT_TYPE, elementType);
87-
builder = builder.queryParam(QUERY_PARAM_INFO_TYPE, infoType);
88-
Map<String, String> optionalParams = new HashMap<>();
89-
optionalParams.put(QUERY_PARAM_DC_POWERFACTOR, String.valueOf(dcPowerFactor));
90-
InfoTypeParameters infoTypeParameters = InfoTypeParameters.builder()
91-
.optionalParameters(optionalParams)
92-
.build();
93-
queryParamInfoTypeParameters(infoTypeParameters, builder);
86+
builder = builder.queryParam(QUERY_PARAM_INFO_TYPE, infoType)
87+
.queryParam(QUERY_PARAM_ELEMENT_TYPE, elementType);
88+
queryParamInfoTypeParameters(InfoTypeParameters.builder()
89+
.optionalParameters(optionalParameters)
90+
.build(), builder);
9491

9592
try {
9693
return restTemplate.getForObject(networkMapServerBaseUri + builder.build().toUriString(), String.class, networkUuid, elementId);
@@ -105,6 +102,25 @@ public String getElementInfos(UUID networkUuid, String variantId, String element
105102
}
106103
}
107104

105+
public String getAllElementsInfos(UUID networkUuid,
106+
String variantId,
107+
List<String> substationsIds,
108+
Map<String, Map<String, String>> optionalParameters) {
109+
String path = DELIMITER + NETWORK_MAP_API_VERSION + "/networks/{networkUuid}/all";
110+
UriComponentsBuilder builder = UriComponentsBuilder.fromPath(path);
111+
if (!StringUtils.isBlank(variantId)) {
112+
builder = builder.queryParam(QUERY_PARAM_VARIANT_ID, variantId);
113+
}
114+
builder = builder.queryParam(QUERY_PARAM_INFO_TYPE, "TAB");
115+
if (substationsIds != null) {
116+
builder = builder.queryParam(QUERY_PARAM_SUBSTATION_ID, substationsIds);
117+
}
118+
HttpHeaders headers = new HttpHeaders();
119+
headers.setContentType(MediaType.APPLICATION_JSON);
120+
HttpEntity<?> httpEntity = new HttpEntity<>(optionalParameters, headers);
121+
return restTemplate.postForObject(networkMapServerBaseUri + builder.buildAndExpand(networkUuid).toUriString(), httpEntity, String.class);
122+
}
123+
108124
private void queryParamInfoTypeParameters(InfoTypeParameters infoTypesParameters, UriComponentsBuilder builder) {
109125
infoTypesParameters.getOptionalParameters().forEach((key, value) -> builder.queryParam(String.format(QUERY_FORMAT_OPTIONAL_PARAMS, key), value));
110126
}
@@ -164,8 +180,7 @@ public String getElementsIds(UUID networkUuid, String variantId, List<String> su
164180
return restTemplate.postForObject(networkMapServerBaseUri + url, httpEntity, String.class);
165181
}
166182

167-
public String getEquipmentsMapData(UUID networkUuid, String variantId, List<String> substationsIds,
168-
String equipmentPath) {
183+
public String getEquipmentsMapData(UUID networkUuid, String variantId, List<String> substationsIds, String equipmentPath) {
169184
String path = DELIMITER + NETWORK_MAP_API_VERSION + "/networks/{networkUuid}/" + equipmentPath;
170185
UriComponentsBuilder builder = UriComponentsBuilder
171186
.fromPath(path);

0 commit comments

Comments
 (0)