Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/gridsuite/explore-server in…
Browse files Browse the repository at this point in the history
…to Delete-reference-to-a-specific-type

# Conflicts:
#	src/main/java/org/gridsuite/explore/server/services/ExploreService.java
  • Loading branch information
AAJELLAL committed Jul 4, 2024
2 parents 9577b67 + b21bd3d commit 45fd7b1
Show file tree
Hide file tree
Showing 14 changed files with 401 additions and 107 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
</developers>

<properties>
<gridsuite-dependencies.version>29</gridsuite-dependencies.version>
<gridsuite-dependencies.version>30</gridsuite-dependencies.version>
</properties>

<build>
Expand Down
65 changes: 37 additions & 28 deletions src/main/java/org/gridsuite/explore/server/ExploreController.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ public enum Type {
UNKNOWN_ELEMENT_TYPE,
REMOTE_ERROR,
IMPORT_CASE_FAILED,
INCORRECT_CASE_FILE
INCORRECT_CASE_FILE,
MAX_ELEMENTS_EXCEEDED,
}

private final Type type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ protected ResponseEntity<Object> handleExploreException(ExploreException excepti
return ResponseEntity.status(HttpStatus.UNPROCESSABLE_ENTITY).body(exception.getMessage());
case UNKNOWN_ELEMENT_TYPE:
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(UNKNOWN_ELEMENT_TYPE);
case MAX_ELEMENTS_EXCEEDED:
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(MAX_ELEMENTS_EXCEEDED + " " + exception.getMessage());
default:
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.stream.Collectors;

import static org.gridsuite.explore.server.ExploreException.Type.*;
import static org.gridsuite.explore.server.utils.ExploreUtils.wrapRemoteError;

@Service
public class CaseService implements IDirectoryElementsService {
Expand All @@ -43,14 +44,6 @@ public CaseService(@Value("${powsybl.services.case-server.base-uri:http://case-s
this.restTemplate = restTemplate;
}

private static ExploreException wrapRemoteError(String response, HttpStatusCode statusCode) {
if (!"".equals(response)) {
throw new ExploreException(ExploreException.Type.REMOTE_ERROR, response);
} else {
throw new ExploreException(ExploreException.Type.REMOTE_ERROR, "{\"message\": " + statusCode + "\"}");
}
}

public void setBaseUri(String actionsServerBaseUri) {
this.caseServerBaseUri = actionsServerBaseUri;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ public class DirectoryService implements IDirectoryElementsService {
private static final String ELEMENTS_SERVER_ROOT_PATH = DELIMITER + DIRECTORY_SERVER_API_VERSION + DELIMITER
+ "elements";

private static final String ELEMENTS_SERVER_ELEMENT_PATH = ELEMENTS_SERVER_ROOT_PATH + DELIMITER
+ "{elementUuid}";

private static final String PARAM_IDS = "ids";
private static final String PARAM_FOR_DELETION = "forDeletion";
private static final String PARAM_TARGET_DIRECTORY_UUID = "targetDirectoryUuid";
Expand All @@ -54,17 +57,19 @@ public DirectoryService(
CaseService caseService, ParametersService parametersService, RestTemplate restTemplate, RemoteServicesProperties remoteServicesProperties) {
this.directoryServerBaseUri = remoteServicesProperties.getServiceUri("directory-server");
this.restTemplate = restTemplate;
this.genericServices = Map.of(
FILTER, filterService,
CONTINGENCY_LIST, contingencyListService,
STUDY, studyService,
DIRECTORY, this,
MODIFICATION, networkModificationService,
CASE, caseService,
ParametersType.VOLTAGE_INIT_PARAMETERS.name(), parametersService,
ParametersType.SECURITY_ANALYSIS_PARAMETERS.name(), parametersService,
ParametersType.LOADFLOW_PARAMETERS.name(), parametersService,
ParametersType.SENSITIVITY_PARAMETERS.name(), parametersService);
this.genericServices = Map.ofEntries(
Map.entry(FILTER, filterService),
Map.entry(CONTINGENCY_LIST, contingencyListService),
Map.entry(STUDY, studyService),
Map.entry(DIRECTORY, this),
Map.entry(MODIFICATION, networkModificationService),
Map.entry(CASE, caseService),
Map.entry(ParametersType.VOLTAGE_INIT_PARAMETERS.name(), parametersService),
Map.entry(ParametersType.SECURITY_ANALYSIS_PARAMETERS.name(), parametersService),
Map.entry(ParametersType.LOADFLOW_PARAMETERS.name(), parametersService),
Map.entry(ParametersType.SENSITIVITY_PARAMETERS.name(), parametersService),
Map.entry(ParametersType.SHORT_CIRCUIT_PARAMETERS.name(), parametersService)
);
}

public void setDirectoryServerBaseUri(String directoryServerBaseUri) {
Expand Down Expand Up @@ -109,7 +114,7 @@ public ElementAttributes duplicateElement(UUID elementUuid, UUID newElementUuid,

public void deleteDirectoryElement(UUID elementUuid, String userId) {
String path = UriComponentsBuilder
.fromPath(ELEMENTS_SERVER_ROOT_PATH + "/{elementUuid}")
.fromPath(ELEMENTS_SERVER_ELEMENT_PATH)
.buildAndExpand(elementUuid)
.toUriString();
HttpHeaders headers = new HttpHeaders();
Expand Down Expand Up @@ -163,7 +168,7 @@ public void deleteElementsFromDirectory(List<UUID> elementUuids, UUID parentDire

public ElementAttributes getElementInfos(UUID elementUuid) {
String path = UriComponentsBuilder
.fromPath(ELEMENTS_SERVER_ROOT_PATH + "/{elementUuid}")
.fromPath(ELEMENTS_SERVER_ELEMENT_PATH)
.buildAndExpand(elementUuid)
.toUriString();
return restTemplate.exchange(directoryServerBaseUri + path, HttpMethod.GET, null, ElementAttributes.class)
Expand All @@ -182,16 +187,25 @@ public List<ElementAttributes> getElementsInfos(List<UUID> elementsUuids, List<S
elementAttributesList = restTemplate.exchange(directoryServerBaseUri + path, HttpMethod.GET, null,
new ParameterizedTypeReference<List<ElementAttributes>>() {
}).getBody();
if (elementAttributesList != null) {
return elementAttributesList;
} else {
return Collections.emptyList();
return Objects.requireNonNullElse(elementAttributesList, Collections.emptyList());
}

public int getUserCasesCount(String userId) {
String path = UriComponentsBuilder
.fromPath(DELIMITER + DIRECTORY_SERVER_API_VERSION + DELIMITER + "users/{userId}/cases/count")
.buildAndExpand(userId)
.toUriString();

Integer casesCount = restTemplate.exchange(directoryServerBaseUri + path, HttpMethod.GET, null, Integer.class).getBody();
if (casesCount == null) {
throw new ExploreException(REMOTE_ERROR, "Could not get cases count");
}
return casesCount;
}

public void notifyDirectoryChanged(UUID elementUuid, String userId) {
String path = UriComponentsBuilder
.fromPath(ELEMENTS_SERVER_ROOT_PATH + "/{elementUuid}/notification?type={update_directory}")
.fromPath(ELEMENTS_SERVER_ELEMENT_PATH + "/notification?type={update_directory}")
.buildAndExpand(elementUuid, NotificationType.UPDATE_DIRECTORY.name())
.toUriString();

Expand All @@ -211,11 +225,7 @@ private List<ElementAttributes> getDirectoryElements(UUID directoryUuid, String
new HttpEntity<>(headers), new ParameterizedTypeReference<List<ElementAttributes>>() {
}).getBody();

if (elementAttributesList != null) {
return elementAttributesList;
} else {
return Collections.emptyList();
}
return Objects.requireNonNullElse(elementAttributesList, Collections.emptyList());
}

public void deleteElement(UUID id, String userId) {
Expand Down Expand Up @@ -255,7 +265,7 @@ public List<ElementAttributes> getElementsMetadata(List<UUID> ids, List<String>

public void updateElement(UUID elementUuid, ElementAttributes elementAttributes, String userId) {
String path = UriComponentsBuilder
.fromPath(ELEMENTS_SERVER_ROOT_PATH + "/{elementUuid}")
.fromPath(ELEMENTS_SERVER_ELEMENT_PATH)
.buildAndExpand(elementUuid)
.toUriString();
HttpHeaders headers = new HttpHeaders();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@
import java.util.Map;
import java.util.UUID;

import static org.gridsuite.explore.server.ExploreException.Type.NOT_ALLOWED;
import static org.gridsuite.explore.server.ExploreException.Type.UNKNOWN_ELEMENT_TYPE;
import static org.gridsuite.explore.server.ExploreException.Type.*;


/**
Expand All @@ -47,15 +46,16 @@ public class ExploreService {
private final ParametersService parametersService;

private static final Logger LOGGER = LoggerFactory.getLogger(ExploreService.class);
private final UserAdminService userAdminService;

public ExploreService(
DirectoryService directoryService,
StudyService studyService,
ContingencyListService contingencyListService,
FilterService filterService,
NetworkModificationService networkModificationService,
CaseService caseService,
ParametersService parametersService) {
DirectoryService directoryService,
StudyService studyService,
ContingencyListService contingencyListService,
FilterService filterService,
NetworkModificationService networkModificationService,
CaseService caseService,
ParametersService parametersService, UserAdminService userAdminService) {

this.directoryService = directoryService;
this.studyService = studyService;
Expand All @@ -64,6 +64,7 @@ public ExploreService(
this.networkModificationService = networkModificationService;
this.caseService = caseService;
this.parametersService = parametersService;
this.userAdminService = userAdminService;
}

public void createStudy(String studyName, CaseInfo caseInfo, String description, String userId, UUID parentDirectoryUuid, Map<String, Object> importParams, Boolean duplicateCase) {
Expand Down Expand Up @@ -198,7 +199,6 @@ public void deleteElementsFromDirectory(List<UUID> uuids, UUID parentDirectoryUu
LOGGER.error(e.toString(), e);
} finally {
directoryService.deleteElementsFromDirectory(uuids, parentDirectoryUuids, userId);
//
}
}

Expand All @@ -213,7 +213,7 @@ public void updateContingencyList(UUID id, String content, String userId, String
}

private void updateElementName(UUID id, String name, String userId) {
/** if the name is empty, no need to call directory-server */
// if the name is empty, no need to call directory-server
if (StringUtils.isNotBlank(name)) {
ElementAttributes elementAttributes = new ElementAttributes();
elementAttributes.setElementName(name);
Expand Down Expand Up @@ -250,23 +250,14 @@ public void duplicateParameters(UUID sourceId, UUID targetDirectoryId, Parameter
directoryService.duplicateElement(sourceId, newParametersUuid, targetDirectoryId, userId);
}

public void createNetworkModifications(List<ElementAttributes> modificationAttributesList, String userId, UUID parentDirectoryUuid) {
List<UUID> existingModificationsUuids = modificationAttributesList.stream()
.map(ElementAttributes::getElementUuid)
.toList();

// create all duplicated modifications
Map<UUID, UUID> newModificationsUuids = networkModificationService.duplicateModifications(existingModificationsUuids);

// create all corresponding directory elements
modificationAttributesList.forEach(m -> {
final UUID newId = newModificationsUuids.get(m.getElementUuid());
if (newId != null) {
// an Id may be null if a duplication could not succeed (ex: we provide a bad uuid)
ElementAttributes elementAttributes = new ElementAttributes(newId, m.getElementName(), MODIFICATION, userId, 0L, m.getDescription());
directoryService.createElementWithNewName(elementAttributes, parentDirectoryUuid, userId, true);
}
});
public void createCompositeModifications(List<UUID> modificationUuids, String userId, String name,
String description, UUID parentDirectoryUuid) {

// create composite modifications
UUID modificationsUuid = networkModificationService.createCompositeModifications(modificationUuids);
ElementAttributes elementAttributes = new ElementAttributes(modificationsUuid, name, MODIFICATION,
userId, 0L, description);
directoryService.createElementWithNewName(elementAttributes, parentDirectoryUuid, userId, true);
}

public void duplicateNetworkModifications(UUID sourceId, UUID parentDirectoryUuid, String userId) {
Expand All @@ -277,6 +268,16 @@ public void duplicateNetworkModifications(UUID sourceId, UUID parentDirectoryUui
directoryService.duplicateElement(sourceId, newNetworkModification, parentDirectoryUuid, userId);
}

public void assertCanCreateCase(String userId) {
Integer userMaxAllowedStudiesAndCases = userAdminService.getUserMaxAllowedCases(userId);
if (userMaxAllowedStudiesAndCases != null) {
int userCasesCount = directoryService.getUserCasesCount(userId);
if (userCasesCount >= userMaxAllowedStudiesAndCases) {
throw new ExploreException(MAX_ELEMENTS_EXCEEDED, "max allowed cases : " + userMaxAllowedStudiesAndCases);
}
}
}

public void updateElement(UUID id, ElementAttributes elementAttributes, String userId) {
directoryService.updateElement(id, elementAttributes, userId);
ElementAttributes elementsInfos = directoryService.getElementInfos(id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class NetworkModificationService implements IDirectoryElementsService {
private static final String DELIMITER = "/";
private static final String HEADER_USER_ID = "userId";
public static final String UUIDS = "uuids";
public static final String NETWORK_COMPOSITE_MODIFICATIONS_PATH = "network-composite-modifications";
private static final String NETWORK_MODIFICATIONS_PATH = "network-modifications";
private String networkModificationServerBaseUri;
private final RestTemplate restTemplate;
Expand All @@ -54,6 +55,16 @@ public Map<UUID, UUID> duplicateModifications(List<UUID> modificationUuids) {
.getBody();
}

public UUID createCompositeModifications(List<UUID> modificationUuids) {
String path = UriComponentsBuilder.fromPath(DELIMITER + NETWORK_MODIFICATION_API_VERSION + DELIMITER + NETWORK_COMPOSITE_MODIFICATIONS_PATH)
.buildAndExpand()
.toUriString();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return restTemplate.exchange(networkModificationServerBaseUri + path, HttpMethod.POST, new HttpEntity<>(modificationUuids, headers), new ParameterizedTypeReference<UUID>() { })
.getBody();
}

@Override
public void delete(UUID id, String userId) {
String path = UriComponentsBuilder.fromPath(DELIMITER + NETWORK_MODIFICATION_API_VERSION + DELIMITER + NETWORK_MODIFICATIONS_PATH)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ public class ParametersService implements IDirectoryElementsService {
private final Map<ParametersType, String> genericParametersServices = Map.of(ParametersType.VOLTAGE_INIT_PARAMETERS, "voltage-init-server",
ParametersType.SECURITY_ANALYSIS_PARAMETERS, "security-analysis-server",
ParametersType.LOADFLOW_PARAMETERS, "loadflow-server",
ParametersType.SENSITIVITY_PARAMETERS, "sensitivity-analysis-server");
ParametersType.SENSITIVITY_PARAMETERS, "sensitivity-analysis-server",
ParametersType.SHORT_CIRCUIT_PARAMETERS, "shortcircuit-server");

private RemoteServicesProperties remoteServicesProperties;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* 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.explore.server.services;

import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import static org.gridsuite.explore.server.utils.ExploreUtils.wrapRemoteError;

/**
* @author Abdelsalem Hedhili <abdelsalem.hedhili at rte-france.com>
*/
@Service
public class UserAdminService {

private static final String USER_ADMIN_API_VERSION = "v1";
private static final String USERS_MAX_ALLOWED_CASES_URI = "/users/{sub}/profile/max-cases";

private static final String DELIMITER = "/";
private final RestTemplate restTemplate;
@Setter
private String userAdminServerBaseUri;

@Autowired
public UserAdminService(RestTemplate restTemplate, RemoteServicesProperties remoteServicesProperties) {
this.userAdminServerBaseUri = remoteServicesProperties.getServiceUri("user-admin-server");
this.restTemplate = restTemplate;
}

public Integer getUserMaxAllowedCases(String sub) {
String path = UriComponentsBuilder.fromPath(DELIMITER + USER_ADMIN_API_VERSION + USERS_MAX_ALLOWED_CASES_URI)
.buildAndExpand(sub).toUriString();
try {
return restTemplate.getForObject(userAdminServerBaseUri + path, Integer.class);
} catch (HttpStatusCodeException e) {
if (e.getStatusCode().value() == 404) {
return null; // no profile == unlimited import
}
throw wrapRemoteError(e.getMessage(), e.getStatusCode());

}
}

}
29 changes: 29 additions & 0 deletions src/main/java/org/gridsuite/explore/server/utils/ExploreUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* 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.explore.server.utils;

import org.gridsuite.explore.server.ExploreException;
import org.springframework.http.HttpStatusCode;

/**
* @author Abdelsalem Hedhili <abdelsalem.hedhili at rte-france.com
*/
public final class ExploreUtils {

private ExploreUtils() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}

public static ExploreException wrapRemoteError(String response, HttpStatusCode statusCode) {
if (!"".equals(response)) {
throw new ExploreException(ExploreException.Type.REMOTE_ERROR, response);
} else {
throw new ExploreException(ExploreException.Type.REMOTE_ERROR, "{\"message\": " + statusCode + "\"}");
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ public enum ParametersType {
VOLTAGE_INIT_PARAMETERS,
SECURITY_ANALYSIS_PARAMETERS,
LOADFLOW_PARAMETERS,
SENSITIVITY_PARAMETERS
SENSITIVITY_PARAMETERS,
SHORT_CIRCUIT_PARAMETERS
}
Loading

0 comments on commit 45fd7b1

Please sign in to comment.