Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use study-config-server to store network visualization parameters per study #649

Merged
merged 10 commits into from
Dec 19, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ private StudyConstants() {
public static final String SINGLE_LINE_DIAGRAM_API_VERSION = "v1";
public static final String NETWORK_CONVERSION_API_VERSION = "v1";
public static final String GEO_DATA_API_VERSION = "v1";
public static final String NETWORK_STORE_API_VERSION = "v1";
public static final String STUDY_CONFIG_API_VERSION = "v1";
public static final String NETWORK_MODIFICATION_API_VERSION = "v1";
public static final String LOADFLOW_API_VERSION = "v1";
public static final String USER_ADMIN_API_VERSION = "v1";
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/org/gridsuite/study/server/StudyController.java
Original file line number Diff line number Diff line change
Expand Up @@ -1714,6 +1714,25 @@ public ResponseEntity<Void> copyVoltageInitModifications(@PathVariable("studyUui
return ResponseEntity.ok().build();
}

@GetMapping(value = "/studies/{studyUuid}/network-visualizations/parameters")
@Operation(summary = "Get network visualization parameters on study")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The network visualization parameters")})
public ResponseEntity<String> getNetworkVisualizationParametersValues(
@PathVariable("studyUuid") UUID studyUuid) {
return ResponseEntity.ok().body(studyService.getNetworkVisualizationParametersValues(studyUuid));
}

@PostMapping(value = "/studies/{studyUuid}/network-visualizations/parameters")
@Operation(summary = "set network visualization parameters on study")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The network visualization parameters are set")})
public ResponseEntity<Void> setNetworkVisualizationParametersValues(
@PathVariable("studyUuid") UUID studyUuid,
@RequestBody(required = false) String networkVisualizationParametersValues,
@RequestHeader(HEADER_USER_ID) String userId) {
studyService.setNetworkVisualizationParametersValues(studyUuid, networkVisualizationParametersValues, userId);
return ResponseEntity.ok().build();
}

@GetMapping(value = "/optional-services")
@Operation(summary = "Get all the optional services and their status")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "List of optional services")})
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/org/gridsuite/study/server/StudyException.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ public enum Type {
STATE_ESTIMATION_NOT_FOUND,
STATE_ESTIMATION_ERROR,
MAX_NODE_BUILDS_EXCEEDED,
CREATE_NETWORK_VISUALIZATION_PARAMETERS_FAILED,
UPDATE_NETWORK_VISUALIZATION_PARAMETERS_FAILED,
NETWORK_VISUALIZATION_PARAMETERS_NOT_FOUND,
GET_NETWORK_VISUALIZATION_PARAMETERS_FAILED,
ROOT_NETWORK_NOT_FOUND,
ROOT_NETWORK_CREATION_FAILED
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ public class NotificationService {
public static final String UPDATE_TYPE_STATE_ESTIMATION_RESULT = "stateEstimationResult";
public static final String UPDATE_TYPE_STATE_ESTIMATION_STATUS = "stateEstimation_status";
public static final String UPDATE_TYPE_COMPUTATION_PARAMETERS = "computationParametersUpdated";
public static final String UPDATE_NETWORK_VISUALIZATION_PARAMETERS = "networkVisualizationParametersUpdated";

public static final String MODIFICATIONS_CREATING_IN_PROGRESS = "creatingInProgress";
public static final String MODIFICATIONS_STASHING_IN_PROGRESS = "stashingInProgress";
Expand Down Expand Up @@ -178,6 +179,14 @@ public void emitComputationParamsChanged(UUID studyUuid, ComputationType computa
.build());
}

@PostCompletion
public void emitNetworkVisualizationParamsChanged(UUID studyUuid) {
sendUpdateMessage(MessageBuilder.withPayload("")
.setHeader(HEADER_STUDY_UUID, studyUuid)
.setHeader(HEADER_UPDATE_TYPE, UPDATE_NETWORK_VISUALIZATION_PARAMETERS)
.build());
}

public void emitStudyCreationError(UUID studyUuid, String userId, String errorMessage) {
sendUpdateMessage(MessageBuilder.withPayload("")
.setHeader(HEADER_STUDY_UUID, studyUuid)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ public class StudyEntity extends AbstractManuallyAssignedIdentifierEntity<UUID>
@Column(name = "sensitivityAnalysisParametersUuid")
private UUID sensitivityAnalysisParametersUuid;

@Column(name = "networkVisualizationParametersUuid")
private UUID networkVisualizationParametersUuid;

@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
@JoinColumn(name = "nonEvacuatedEnergyParametersEntity_id",
referencedColumnName = "id",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public class ConsumerService {
private final LoadFlowService loadFlowService;
private final UserAdminService userAdminService;
private final NetworkModificationTreeService networkModificationTreeService;
private final StudyConfigService studyConfigService;
private final ShortCircuitService shortCircuitService;
private final RootNetworkNodeInfoService rootNetworkNodeInfoService;
private final VoltageInitService voltageInitService;
Expand All @@ -80,6 +81,7 @@ public ConsumerService(ObjectMapper objectMapper,
UserAdminService userAdminService,
NetworkModificationTreeService networkModificationTreeService,
SensitivityAnalysisService sensitivityAnalysisService,
StudyConfigService studyConfigService,
RootNetworkNodeInfoService rootNetworkNodeInfoService,
VoltageInitService voltageInitService) {
this.objectMapper = objectMapper;
Expand All @@ -91,6 +93,7 @@ public ConsumerService(ObjectMapper objectMapper,
this.userAdminService = userAdminService;
this.networkModificationTreeService = networkModificationTreeService;
this.sensitivityAnalysisService = sensitivityAnalysisService;
this.studyConfigService = studyConfigService;
this.shortCircuitService = shortCircuitService;
this.rootNetworkNodeInfoService = rootNetworkNodeInfoService;
this.voltageInitService = voltageInitService;
Expand Down Expand Up @@ -251,11 +254,12 @@ private void insertStudy(UUID studyUuid, String userId, NetworkInfos networkInfo
UUID shortCircuitParametersUuid = createDefaultShortCircuitAnalysisParameters(userId, userProfileInfos);
UUID securityAnalysisParametersUuid = createDefaultSecurityAnalysisParameters(userId, userProfileInfos);
UUID sensitivityAnalysisParametersUuid = createDefaultSensitivityAnalysisParameters(userId, userProfileInfos);
UUID networkVisualizationParametersUuid = createDefaultNetworkVisualizationParameters();
UUID voltageInitParametersUuid = createDefaultVoltageInitParameters(userId, userProfileInfos);

studyService.insertStudy(studyUuid, userId, networkInfos, caseInfos, loadFlowParametersUuid,
shortCircuitParametersUuid, DynamicSimulationService.toEntity(dynamicSimulationParameters, objectMapper),
voltageInitParametersUuid, securityAnalysisParametersUuid, sensitivityAnalysisParametersUuid,
voltageInitParametersUuid, securityAnalysisParametersUuid, sensitivityAnalysisParametersUuid, networkVisualizationParametersUuid,
importParameters, importReportUuid);
}

Expand Down Expand Up @@ -368,6 +372,15 @@ private UUID createDefaultVoltageInitParameters(String userId, UserProfileInfos
}
}

private UUID createDefaultNetworkVisualizationParameters() {
try {
return studyConfigService.createDefaultNetworkVisualizationParameters();
} catch (final Exception e) {
LOGGER.error("Error while creating network visualization default parameters", e);
return null;
}
}

@Bean
public Consumer<Message<String>> consumeCaseImportFailed() {
return message -> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/**
* Copyright (c) 2024, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.gridsuite.study.server.service;

import lombok.Setter;
import org.gridsuite.study.server.RemoteServicesProperties;
import org.gridsuite.study.server.StudyException;
import org.gridsuite.study.server.repository.StudyEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.Objects;
import java.util.UUID;

import static org.gridsuite.study.server.StudyConstants.DELIMITER;
import static org.gridsuite.study.server.StudyConstants.STUDY_CONFIG_API_VERSION;
import static org.gridsuite.study.server.StudyException.Type.*;
import static org.gridsuite.study.server.utils.StudyUtils.handleHttpError;

/**
* @author David BRAQUART <david.braquart at rte-france.com>
*/
@Service
public class StudyConfigService {

private static final String NETWORK_VISU_PARAMETERS_URI = "/network-visualizations-params";
private static final String NETWORK_VISU_PARAMETERS_WITH_ID_URI = NETWORK_VISU_PARAMETERS_URI + "/{uuid}";

private final RestTemplate restTemplate;

@Setter
private String studyConfigServerBaseUri;

@Autowired
public StudyConfigService(RemoteServicesProperties remoteServicesProperties, RestTemplate restTemplate) {
this.studyConfigServerBaseUri = remoteServicesProperties.getServiceUri("spreadsheet-config-server");
this.restTemplate = restTemplate;
}

public void updateNetworkVisualizationParameters(UUID parametersUuid, String parameters) {
var uriBuilder = UriComponentsBuilder.fromPath(DELIMITER + STUDY_CONFIG_API_VERSION + NETWORK_VISU_PARAMETERS_WITH_ID_URI);
String path = uriBuilder.buildAndExpand(parametersUuid).toUriString();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> httpEntity = new HttpEntity<>(parameters, headers);
try {
restTemplate.put(studyConfigServerBaseUri + path, httpEntity);
} catch (HttpStatusCodeException e) {
throw handleHttpError(e, UPDATE_NETWORK_VISUALIZATION_PARAMETERS_FAILED);
}
}

public UUID duplicateNetworkVisualizationParameters(UUID sourceParametersUuid) {
Objects.requireNonNull(sourceParametersUuid);
var path = UriComponentsBuilder.fromPath(DELIMITER + STUDY_CONFIG_API_VERSION + NETWORK_VISU_PARAMETERS_URI + "/duplicate")
.queryParam("duplicateFrom", sourceParametersUuid)
.buildAndExpand().toUriString();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Void> httpEntity = new HttpEntity<>(null, headers);
try {
return restTemplate.exchange(studyConfigServerBaseUri + path, HttpMethod.POST, httpEntity, UUID.class).getBody();
} catch (HttpStatusCodeException e) {
throw handleHttpError(e, CREATE_NETWORK_VISUALIZATION_PARAMETERS_FAILED);
}
}

public String getNetworkVisualizationParameters(UUID parametersUuid) {
Objects.requireNonNull(parametersUuid);
String parameters;
String path = UriComponentsBuilder.fromPath(DELIMITER + STUDY_CONFIG_API_VERSION + NETWORK_VISU_PARAMETERS_WITH_ID_URI)
.buildAndExpand(parametersUuid).toUriString();
try {
parameters = restTemplate.getForObject(studyConfigServerBaseUri + path, String.class);
} catch (HttpStatusCodeException e) {
if (HttpStatus.NOT_FOUND.equals(e.getStatusCode())) {
throw new StudyException(NETWORK_VISUALIZATION_PARAMETERS_NOT_FOUND);
}
throw handleHttpError(e, GET_NETWORK_VISUALIZATION_PARAMETERS_FAILED);
}
return parameters;
}

public UUID getNetworkVisualizationParametersUuidOrElseCreateDefaults(StudyEntity studyEntity) {
if (studyEntity.getNetworkVisualizationParametersUuid() == null) {
studyEntity.setNetworkVisualizationParametersUuid(createDefaultNetworkVisualizationParameters());
}
return studyEntity.getNetworkVisualizationParametersUuid();
}

public void deleteNetworkVisualizationParameters(UUID uuid) {
Objects.requireNonNull(uuid);
String path = UriComponentsBuilder.fromPath(DELIMITER + STUDY_CONFIG_API_VERSION + NETWORK_VISU_PARAMETERS_WITH_ID_URI)
.buildAndExpand(uuid)
.toUriString();
restTemplate.delete(studyConfigServerBaseUri + path);
}

public UUID createDefaultNetworkVisualizationParameters() {
var path = UriComponentsBuilder
.fromPath(DELIMITER + STUDY_CONFIG_API_VERSION + NETWORK_VISU_PARAMETERS_URI + "/default")
.buildAndExpand()
.toUriString();
UUID parametersUuid;
try {
parametersUuid = restTemplate.exchange(studyConfigServerBaseUri + path, HttpMethod.POST, null, UUID.class).getBody();
} catch (HttpStatusCodeException e) {
throw handleHttpError(e, CREATE_NETWORK_VISUALIZATION_PARAMETERS_FAILED);
}
return parametersUuid;
}

public UUID createNetworkVisualizationParameters(String parameters) {
var path = UriComponentsBuilder
.fromPath(DELIMITER + STUDY_CONFIG_API_VERSION + NETWORK_VISU_PARAMETERS_URI)
.buildAndExpand()
.toUriString();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> httpEntity = new HttpEntity<>(parameters, headers);
UUID parametersUuid;
try {
parametersUuid = restTemplate.exchange(studyConfigServerBaseUri + path, HttpMethod.POST, httpEntity, UUID.class).getBody();
} catch (HttpStatusCodeException e) {
throw handleHttpError(e, CREATE_NETWORK_VISUALIZATION_PARAMETERS_FAILED);
}
return parametersUuid;
}
}
Loading
Loading