From 72cd1501de51977d3f20e46e091bc1038112f52a Mon Sep 17 00:00:00 2001 From: Ghazoua Rehili Date: Wed, 26 Jun 2024 17:45:53 +0200 Subject: [PATCH] add composite network modification (#89) Signed-off-by: REHILI Ghazwa --- .../explore/server/ExploreController.java | 61 ++++++++++--------- .../server/services/ExploreService.java | 27 +++----- .../services/NetworkModificationService.java | 11 ++++ .../gridsuite/explore/server/ExploreTest.java | 22 +++---- 4 files changed, 62 insertions(+), 59 deletions(-) diff --git a/src/main/java/org/gridsuite/explore/server/ExploreController.java b/src/main/java/org/gridsuite/explore/server/ExploreController.java index 3e34701..4e14fde 100644 --- a/src/main/java/org/gridsuite/explore/server/ExploreController.java +++ b/src/main/java/org/gridsuite/explore/server/ExploreController.java @@ -33,9 +33,12 @@ public class ExploreController { // /!\ This query parameter is used by the gateway to control access + private static final String QUERY_PARAM_NAME = "name"; + private static final String QUERY_PARAM_DESCRIPTION = "description"; private static final String QUERY_PARAM_PARENT_DIRECTORY_ID = "parentDirectoryUuid"; private static final String QUERY_PARAM_TYPE = "type"; + private static final String QUERY_PARAM_USER_ID = "userId"; private final ExploreService exploreService; private final DirectoryService directoryService; @@ -54,7 +57,7 @@ public ResponseEntity createStudy(@PathVariable("studyName") String studyN @RequestParam(name = "duplicateCase", required = false, defaultValue = "false") Boolean duplicateCase, @RequestParam("description") String description, @RequestParam(QUERY_PARAM_PARENT_DIRECTORY_ID) UUID parentDirectoryUuid, - @RequestHeader("userId") String userId, + @RequestHeader(QUERY_PARAM_USER_ID) String userId, @RequestBody(required = false) Map importParams) { exploreService.assertCanCreateCase(userId); CaseInfo caseInfo = new CaseInfo(caseUuid, caseFormat); @@ -67,7 +70,7 @@ public ResponseEntity createStudy(@PathVariable("studyName") String studyN @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Study creation request delegated to study server")}) public ResponseEntity duplicateStudy(@RequestParam("duplicateFrom") UUID studyId, @RequestParam(name = QUERY_PARAM_PARENT_DIRECTORY_ID, required = false) UUID targetDirectoryId, - @RequestHeader("userId") String userId) { + @RequestHeader(QUERY_PARAM_USER_ID) String userId) { exploreService.assertCanCreateCase(userId); exploreService.duplicateStudy(studyId, targetDirectoryId, userId); return ResponseEntity.ok().build(); @@ -80,7 +83,7 @@ public ResponseEntity createCase(@PathVariable("caseName") String caseName @RequestPart("caseFile") MultipartFile caseFile, @RequestParam("description") String description, @RequestParam(QUERY_PARAM_PARENT_DIRECTORY_ID) UUID parentDirectoryUuid, - @RequestHeader("userId") String userId) { + @RequestHeader(QUERY_PARAM_USER_ID) String userId) { exploreService.assertCanCreateCase(userId); exploreService.createCase(caseName, caseFile, description, userId, parentDirectoryUuid); return ResponseEntity.ok().build(); @@ -92,7 +95,7 @@ public ResponseEntity createCase(@PathVariable("caseName") String caseName public ResponseEntity duplicateCase( @RequestParam("duplicateFrom") UUID caseId, @RequestParam(name = QUERY_PARAM_PARENT_DIRECTORY_ID, required = false) UUID targetDirectoryId, - @RequestHeader("userId") String userId) { + @RequestHeader(QUERY_PARAM_USER_ID) String userId) { exploreService.assertCanCreateCase(userId); exploreService.duplicateCase(caseId, targetDirectoryId, userId); return ResponseEntity.ok().build(); @@ -105,7 +108,7 @@ public ResponseEntity createScriptContingencyList(@PathVariable("listName" @RequestBody(required = false) String content, @RequestParam("description") String description, @RequestParam(QUERY_PARAM_PARENT_DIRECTORY_ID) UUID parentDirectoryUuid, - @RequestHeader("userId") String userId) { + @RequestHeader(QUERY_PARAM_USER_ID) String userId) { exploreService.createScriptContingencyList(listName, content, description, userId, parentDirectoryUuid); return ResponseEntity.ok().build(); } @@ -117,7 +120,7 @@ public ResponseEntity duplicateContingencyList( @RequestParam("duplicateFrom") UUID contingencyListUuid, @RequestParam(name = QUERY_PARAM_TYPE) ContingencyListType contingencyListType, @RequestParam(name = QUERY_PARAM_PARENT_DIRECTORY_ID, required = false) UUID targetDirectoryId, - @RequestHeader("userId") String userId) { + @RequestHeader(QUERY_PARAM_USER_ID) String userId) { exploreService.duplicateContingencyList(contingencyListUuid, targetDirectoryId, userId, contingencyListType); return ResponseEntity.ok().build(); } @@ -129,7 +132,7 @@ public ResponseEntity createFormContingencyList(@PathVariable("listName") @RequestBody(required = false) String content, @RequestParam("description") String description, @RequestParam(QUERY_PARAM_PARENT_DIRECTORY_ID) UUID parentDirectoryUuid, - @RequestHeader("userId") String userId) { + @RequestHeader(QUERY_PARAM_USER_ID) String userId) { exploreService.createFormContingencyList(listName, content, description, userId, parentDirectoryUuid); return ResponseEntity.ok().build(); } @@ -140,7 +143,7 @@ public ResponseEntity createFormContingencyList(@PathVariable("listName") public ResponseEntity newScriptFromFormContingencyList(@PathVariable("id") UUID id, @PathVariable("scriptName") String scriptName, @RequestParam(QUERY_PARAM_PARENT_DIRECTORY_ID) UUID parentDirectoryUuid, - @RequestHeader("userId") String userId) { + @RequestHeader(QUERY_PARAM_USER_ID) String userId) { exploreService.newScriptFromFormContingencyList(id, scriptName, userId, parentDirectoryUuid); return ResponseEntity.ok().build(); } @@ -149,7 +152,7 @@ public ResponseEntity newScriptFromFormContingencyList(@PathVariable("id") @Operation(summary = "Replace a form contingency list with a script contingency list") @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The form contingency list has been replaced successfully")}) public ResponseEntity replaceFilterContingencyListWithScript(@PathVariable("id") UUID id, - @RequestHeader("userId") String userId) { + @RequestHeader(QUERY_PARAM_USER_ID) String userId) { exploreService.replaceFormContingencyListWithScript(id, userId); return ResponseEntity.ok().build(); } @@ -161,7 +164,7 @@ public ResponseEntity createIdentifierContingencyList(@PathVariable("listN @RequestBody(required = false) String content, @RequestParam("description") String description, @RequestParam(QUERY_PARAM_PARENT_DIRECTORY_ID) UUID parentDirectoryUuid, - @RequestHeader("userId") String userId) { + @RequestHeader(QUERY_PARAM_USER_ID) String userId) { exploreService.createIdentifierContingencyList(listName, content, description, userId, parentDirectoryUuid); return ResponseEntity.ok().build(); } @@ -173,7 +176,7 @@ public ResponseEntity createFilter(@RequestBody String filter, @RequestParam("name") String filterName, @RequestParam("description") String description, @RequestParam(QUERY_PARAM_PARENT_DIRECTORY_ID) UUID parentDirectoryUuid, - @RequestHeader("userId") String userId) { + @RequestHeader(QUERY_PARAM_USER_ID) String userId) { exploreService.createFilter(filter, filterName, description, parentDirectoryUuid, userId); return ResponseEntity.ok().build(); } @@ -184,7 +187,7 @@ public ResponseEntity createFilter(@RequestBody String filter, public ResponseEntity duplicateFilter( @RequestParam("duplicateFrom") UUID filterId, @RequestParam(name = QUERY_PARAM_PARENT_DIRECTORY_ID, required = false) UUID targetDirectoryId, - @RequestHeader("userId") String userId) { + @RequestHeader(QUERY_PARAM_USER_ID) String userId) { exploreService.duplicateFilter(filterId, targetDirectoryId, userId); return ResponseEntity.ok().build(); } @@ -195,7 +198,7 @@ public ResponseEntity duplicateFilter( public ResponseEntity newScriptFromFilter(@PathVariable("id") UUID filterId, @PathVariable("scriptName") String scriptName, @RequestParam(QUERY_PARAM_PARENT_DIRECTORY_ID) UUID parentDirectoryUuid, - @RequestHeader("userId") String userId) { + @RequestHeader(QUERY_PARAM_USER_ID) String userId) { exploreService.newScriptFromFilter(filterId, scriptName, userId, parentDirectoryUuid); return ResponseEntity.ok().build(); } @@ -204,7 +207,7 @@ public ResponseEntity newScriptFromFilter(@PathVariable("id") UUID filterI @Operation(summary = "Replace a filter with a script") @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The filter has been replaced successfully")}) public ResponseEntity replaceFilterWithScript(@PathVariable("id") UUID id, - @RequestHeader("userId") String userId) { + @RequestHeader(QUERY_PARAM_USER_ID) String userId) { exploreService.replaceFilterWithScript(id, userId); return ResponseEntity.ok().build(); } @@ -217,7 +220,7 @@ public ResponseEntity replaceFilterWithScript(@PathVariable("id") UUID id, @ApiResponse(responseCode = "403", description = "Access forbidden for the directory/element") }) public ResponseEntity deleteElement(@PathVariable("elementUuid") UUID elementUuid, - @RequestHeader("userId") String userId) { + @RequestHeader(QUERY_PARAM_USER_ID) String userId) { exploreService.deleteElement(elementUuid, userId); return ResponseEntity.ok().build(); } @@ -230,7 +233,7 @@ public ResponseEntity deleteElement(@PathVariable("elementUuid") UUID elem @ApiResponse(responseCode = "403", description = "Access forbidden for at least one directory/element") }) public ResponseEntity deleteElements(@RequestParam("ids") List elementsUuid, - @RequestHeader("userId") String userId, + @RequestHeader(QUERY_PARAM_USER_ID) String userId, @PathVariable UUID directoryUuid) { exploreService.deleteElementsFromDirectory(elementsUuid, directoryUuid, userId); return ResponseEntity.ok().build(); @@ -248,7 +251,7 @@ public ResponseEntity> getElementsMetadata(@RequestParam @PutMapping(value = "/explore/filters/{id}", consumes = MediaType.APPLICATION_JSON_VALUE) @Operation(summary = "Modify a filter") @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The filter has been successfully modified")}) - public ResponseEntity changeFilter(@PathVariable UUID id, @RequestBody String filter, @RequestHeader("userId") String userId, @RequestParam("name") String name) { + public ResponseEntity changeFilter(@PathVariable UUID id, @RequestBody String filter, @RequestHeader(QUERY_PARAM_USER_ID) String userId, @RequestParam("name") String name) { exploreService.updateFilter(id, filter, userId, name); return ResponseEntity.ok().build(); } @@ -261,7 +264,7 @@ public ResponseEntity updateContingencyList( @RequestParam(name = "name") String name, @RequestParam(name = "contingencyListType") ContingencyListType contingencyListType, @RequestBody String content, - @RequestHeader("userId") String userId) { + @RequestHeader(QUERY_PARAM_USER_ID) String userId) { exploreService.updateContingencyList(id, content, userId, name, contingencyListType); return ResponseEntity.ok().build(); @@ -274,7 +277,7 @@ public ResponseEntity createParameters(@RequestBody String parameters, @RequestParam("name") String parametersName, @RequestParam(name = QUERY_PARAM_TYPE, defaultValue = "") ParametersType parametersType, @RequestParam(QUERY_PARAM_PARENT_DIRECTORY_ID) UUID parentDirectoryUuid, - @RequestHeader("userId") String userId) { + @RequestHeader(QUERY_PARAM_USER_ID) String userId) { exploreService.createParameters(parameters, parametersType, parametersName, parentDirectoryUuid, userId); return ResponseEntity.ok().build(); } @@ -285,7 +288,7 @@ public ResponseEntity createParameters(@RequestBody String parameters, public ResponseEntity updateParameters(@PathVariable UUID id, @RequestBody String parameters, @RequestParam(name = QUERY_PARAM_TYPE, defaultValue = "") ParametersType parametersType, - @RequestHeader("userId") String userId, + @RequestHeader(QUERY_PARAM_USER_ID) String userId, @RequestParam("name") String name) { exploreService.updateParameters(id, parameters, parametersType, userId, name); return ResponseEntity.ok().build(); @@ -297,18 +300,20 @@ public ResponseEntity updateParameters(@PathVariable UUID id, public ResponseEntity duplicateParameters(@RequestParam("duplicateFrom") UUID parametersId, @RequestParam(name = QUERY_PARAM_PARENT_DIRECTORY_ID, required = false) UUID targetDirectoryId, @RequestParam(name = QUERY_PARAM_TYPE) ParametersType parametersType, - @RequestHeader("userId") String userId) { + @RequestHeader(QUERY_PARAM_USER_ID) String userId) { exploreService.duplicateParameters(parametersId, targetDirectoryId, parametersType, userId); return ResponseEntity.ok().build(); } - @PostMapping(value = "/explore/modifications") - @Operation(summary = "create some modification elements from existing network modifications") - @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Modifications have been duplicated and corresponding elements created in the directory")}) - public ResponseEntity createNetworkModifications(@RequestBody List bodyContent, + @PostMapping(value = "/explore/composite-modifications") + @Operation(summary = "create composite modification element from existing network modifications") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Modifications have been created and composite modification element created in the directory")}) + public ResponseEntity createCompositeModifications(@RequestBody List modificationAttributes, + @RequestParam(QUERY_PARAM_NAME) String name, + @RequestParam(QUERY_PARAM_DESCRIPTION) String description, @RequestParam(QUERY_PARAM_PARENT_DIRECTORY_ID) UUID parentDirectoryUuid, - @RequestHeader("userId") String userId) { - exploreService.createNetworkModifications(bodyContent, userId, parentDirectoryUuid); + @RequestHeader(QUERY_PARAM_USER_ID) String userId) { + exploreService.createCompositeModifications(modificationAttributes, userId, name, description, parentDirectoryUuid); return ResponseEntity.ok().build(); } @@ -317,7 +322,7 @@ public ResponseEntity createNetworkModifications(@RequestBody List duplicateNetworkModifications(@RequestParam("duplicateFrom") UUID networkModificationId, @RequestParam(name = QUERY_PARAM_PARENT_DIRECTORY_ID, required = false) UUID targetDirectoryId, - @RequestHeader("userId") String userId) { + @RequestHeader(QUERY_PARAM_USER_ID) String userId) { exploreService.duplicateNetworkModifications(networkModificationId, targetDirectoryId, userId); return ResponseEntity.ok().build(); } diff --git a/src/main/java/org/gridsuite/explore/server/services/ExploreService.java b/src/main/java/org/gridsuite/explore/server/services/ExploreService.java index c4d8ad3..e0e8bdf 100644 --- a/src/main/java/org/gridsuite/explore/server/services/ExploreService.java +++ b/src/main/java/org/gridsuite/explore/server/services/ExploreService.java @@ -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); @@ -250,23 +250,14 @@ public void duplicateParameters(UUID sourceId, UUID targetDirectoryId, Parameter directoryService.duplicateElement(sourceId, newParametersUuid, targetDirectoryId, userId); } - public void createNetworkModifications(List modificationAttributesList, String userId, UUID parentDirectoryUuid) { - List existingModificationsUuids = modificationAttributesList.stream() - .map(ElementAttributes::getElementUuid) - .toList(); - - // create all duplicated modifications - Map 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 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) { diff --git a/src/main/java/org/gridsuite/explore/server/services/NetworkModificationService.java b/src/main/java/org/gridsuite/explore/server/services/NetworkModificationService.java index 069f5c9..255f90a 100644 --- a/src/main/java/org/gridsuite/explore/server/services/NetworkModificationService.java +++ b/src/main/java/org/gridsuite/explore/server/services/NetworkModificationService.java @@ -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; @@ -54,6 +55,16 @@ public Map duplicateModifications(List modificationUuids) { .getBody(); } + public UUID createCompositeModifications(List 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() { }) + .getBody(); + } + @Override public void delete(UUID id, String userId) { String path = UriComponentsBuilder.fromPath(DELIMITER + NETWORK_MODIFICATION_API_VERSION + DELIMITER + NETWORK_MODIFICATIONS_PATH) diff --git a/src/test/java/org/gridsuite/explore/server/ExploreTest.java b/src/test/java/org/gridsuite/explore/server/ExploreTest.java index 0994aec..1098de0 100644 --- a/src/test/java/org/gridsuite/explore/server/ExploreTest.java +++ b/src/test/java/org/gridsuite/explore/server/ExploreTest.java @@ -77,7 +77,6 @@ public class ExploreTest { private static final UUID CASE_COPY_UUID = UUID.randomUUID(); private static final UUID CONTINGENCY_LIST_COPY_UUID = UUID.randomUUID(); private static final UUID FILTER_COPY_UUID = UUID.randomUUID(); - private static final UUID MODIFICATION_COPY_UUID = UUID.randomUUID(); private static final UUID PARAMETER_COPY_UUID = UUID.randomUUID(); private static final UUID ELEMENT_COPY_UUID = UUID.randomUUID(); private static final String STUDY_ERROR_NAME = "studyInError"; @@ -153,7 +152,7 @@ public void setup() throws IOException { String caseInfosAttributesAsString = mapper.writeValueAsString(List.of(caseSpecificMetadata)); String modificationElementAttributesAsString = mapper.writeValueAsString(new ElementAttributes(MODIFICATION_UUID, "one modif", "MODIFICATION", USER1, 0L, null)); String modificationInfosAttributesAsString = mapper.writeValueAsString(List.of(modificationSpecificMetadata)); - String modificationIdsAsString = mapper.writeValueAsString(Map.of(MODIFICATION_UUID, MODIFICATION_COPY_UUID)); + String compositeModificationIdAsString = mapper.writeValueAsString(MODIFICATION_UUID); String newStudyUuidAsString = mapper.writeValueAsString(STUDY_COPY_UUID); String newCaseUuidAsString = mapper.writeValueAsString(CASE_COPY_UUID); String newContingencyUuidAsString = mapper.writeValueAsString(CONTINGENCY_LIST_COPY_UUID); @@ -288,8 +287,8 @@ public MockResponse dispatch(RecordedRequest request) { .addHeader("Content-Type", "application/json; charset=utf-8"); } else if (path.matches("/v1/parameters.*")) { return new MockResponse().setResponseCode(200); - } else if (path.matches("/v1/network-modifications")) { - return new MockResponse().setBody(modificationIdsAsString).setResponseCode(200).addHeader("Content-Type", "application/json; charset=utf-8"); + } else if (path.matches("/v1/network-composite-modifications")) { + return new MockResponse().setBody(compositeModificationIdAsString).setResponseCode(200).addHeader("Content-Type", "application/json; charset=utf-8"); } else if ("GET".equals(request.getMethod())) { if (path.matches("/v1/elements/" + INVALID_ELEMENT_UUID)) { return new MockResponse().setBody(invalidElementAsString).setResponseCode(200).addHeader("Content-Type", "application/json; charset=utf-8"); @@ -358,7 +357,7 @@ public MockResponse dispatch(RecordedRequest request) { return new MockResponse().setResponseCode(200); } else if (path.matches("/v1/parameters/" + PARAMETERS_UUID)) { return new MockResponse().setResponseCode(200); - } else if (path.matches("\\/v1\\/elements\\?ids=([^,]+,){2,}[^,]+$")) { + } else if (path.matches("/v1/elements\\?ids=([^,]+,){2,}[^,]+$")) { return new MockResponse().setResponseCode(200); } return new MockResponse().setResponseCode(404); @@ -757,16 +756,13 @@ public void testGetMetadata() throws Exception { @Test @SneakyThrows - public void testcreateNetworkModifications() { - final String body = mapper.writeValueAsString(List.of( - new ElementAttributes(MODIFICATION_UUID, "one modif", "", USER1, 0L, "a description"), - new ElementAttributes(UUID.randomUUID(), "2nd modif", "", USER1, 0L, "a description") - ) - ); - mockMvc.perform(post("/v1/explore/modifications?parentDirectoryUuid={parentDirectoryUuid}", PARENT_DIRECTORY_UUID) + public void testCreateNetworkCompositeModifications() { + List modificationUuids = Arrays.asList(MODIFICATION_UUID, UUID.randomUUID()); + mockMvc.perform(post("/v1/explore/composite-modifications?name={name}&description={description}&parentDirectoryUuid={parentDirectoryUuid}", + "nameModif", "descModif", PARENT_DIRECTORY_UUID) .header("userId", USER1) .contentType(MediaType.APPLICATION_JSON) - .content(body) + .content(mapper.writeValueAsString(modificationUuids)) ).andExpect(status().isOk()); }