Skip to content

Commit

Permalink
check user case creation limit (#91)
Browse files Browse the repository at this point in the history
Signed-off-by: Abdelsalem <[email protected]>
  • Loading branch information
AbdelHedhili authored Jun 21, 2024
1 parent 44754a3 commit 81b8b71
Show file tree
Hide file tree
Showing 10 changed files with 310 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public ResponseEntity<Void> createStudy(@PathVariable("studyName") String studyN
@RequestParam(QUERY_PARAM_PARENT_DIRECTORY_ID) UUID parentDirectoryUuid,
@RequestHeader("userId") String userId,
@RequestBody(required = false) Map<String, Object> importParams) {
exploreService.assertCanCreateCase(userId);
CaseInfo caseInfo = new CaseInfo(caseUuid, caseFormat);
exploreService.createStudy(studyName, caseInfo, description, userId, parentDirectoryUuid, importParams, duplicateCase);
return ResponseEntity.ok().build();
Expand All @@ -67,6 +68,7 @@ public ResponseEntity<Void> createStudy(@PathVariable("studyName") String studyN
public ResponseEntity<Void> duplicateStudy(@RequestParam("duplicateFrom") UUID studyId,
@RequestParam(name = QUERY_PARAM_PARENT_DIRECTORY_ID, required = false) UUID targetDirectoryId,
@RequestHeader("userId") String userId) {
exploreService.assertCanCreateCase(userId);
exploreService.duplicateStudy(studyId, targetDirectoryId, userId);
return ResponseEntity.ok().build();
}
Expand All @@ -79,6 +81,7 @@ public ResponseEntity<Void> createCase(@PathVariable("caseName") String caseName
@RequestParam("description") String description,
@RequestParam(QUERY_PARAM_PARENT_DIRECTORY_ID) UUID parentDirectoryUuid,
@RequestHeader("userId") String userId) {
exploreService.assertCanCreateCase(userId);
exploreService.createCase(caseName, caseFile, description, userId, parentDirectoryUuid);
return ResponseEntity.ok().build();
}
Expand All @@ -90,6 +93,7 @@ public ResponseEntity<Void> duplicateCase(
@RequestParam("duplicateFrom") UUID caseId,
@RequestParam(name = QUERY_PARAM_PARENT_DIRECTORY_ID, required = false) UUID targetDirectoryId,
@RequestHeader("userId") String userId) {
exploreService.assertCanCreateCase(userId);
exploreService.duplicateCase(caseId, targetDirectoryId, userId);
return ResponseEntity.ok().build();
}
Expand Down
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 @@ -188,6 +188,19 @@ private List<ElementAttributes> getElementsInfos(List<UUID> elementsUuids, List<
}
}

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}")
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 @@ -275,4 +276,14 @@ public void duplicateNetworkModifications(UUID sourceId, UUID parentDirectoryUui
// create corresponding directory element
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);
}
}
}
}
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 + "\"}");
}
}

}
3 changes: 3 additions & 0 deletions src/main/resources/application-local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,7 @@ gridsuite:
-
name: sensitivity-analysis-server
base-uri: http://localhost:5030
-
name: user-admin-server
base-uri: http://localhost:5033

Loading

0 comments on commit 81b8b71

Please sign in to comment.