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

check user case creation limit #91

Merged
merged 3 commits into from
Jun 21, 2024
Merged
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 @@ -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
Loading