diff --git a/src/main/java/org/gridsuite/study/server/StudyController.java b/src/main/java/org/gridsuite/study/server/StudyController.java index 81d3fbb6f..171ee548d 100644 --- a/src/main/java/org/gridsuite/study/server/StudyController.java +++ b/src/main/java/org/gridsuite/study/server/StudyController.java @@ -413,7 +413,7 @@ public ResponseEntity getLineGraphics( @PathVariable("nodeUuid") UUID nodeUuid, @Parameter(description = "Lines ids") @RequestParam(name = "lineId", required = false) List linesIds) { - return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(studyService.getLinesGraphics(networkStoreService.getNetworkUuid(studyUuid), nodeUuid, linesIds)); + return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(studyService.getLinesGraphics(networkStoreService.getNetworkUuid(studyUuid), nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), linesIds)); } @GetMapping(value = "/studies/{studyUuid}/nodes/{nodeUuid}/geo-data/substations") @@ -424,7 +424,7 @@ public ResponseEntity getSubstationGraphics( @PathVariable("nodeUuid") UUID nodeUuid, @Parameter(description = "Substations id") @RequestParam(name = "substationId", required = false) List substationsIds) { - return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(studyService.getSubstationsGraphics(networkStoreService.getNetworkUuid(studyUuid), nodeUuid, substationsIds)); + return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(studyService.getSubstationsGraphics(networkStoreService.getNetworkUuid(studyUuid), nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), substationsIds)); } @PostMapping(value = "/studies/{studyUuid}/nodes/{nodeUuid}/network-map/equipments-ids") @@ -592,7 +592,7 @@ public ResponseEntity runLoadFlow( @Parameter(description = "The limit reduction") @RequestParam(name = "limitReduction", required = false) Float limitReduction, @RequestHeader(HEADER_USER_ID) String userId) { studyService.assertIsNodeNotReadOnly(nodeUuid); - studyService.runLoadFlow(studyUuid, nodeUuid, userId, limitReduction); + studyService.runLoadFlow(studyUuid, nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), userId, limitReduction); return ResponseEntity.ok().build(); } @@ -605,7 +605,7 @@ public ResponseEntity getLoadflowResult(@Parameter(description = "study @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid, @Parameter(description = "JSON array of filters") @RequestParam(name = "filters", required = false) String filters, Sort sort) { - String result = loadflowService.getLoadFlowResult(nodeUuid, filters, sort); + String result = loadflowService.getLoadFlowResult(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), filters, sort); return result != null ? ResponseEntity.ok().body(result) : ResponseEntity.noContent().build(); } @@ -617,7 +617,7 @@ public ResponseEntity getLoadflowResult(@Parameter(description = "study @ApiResponse(responseCode = "404", description = "The loadflow status has not been found")}) public ResponseEntity getLoadFlowStatus(@Parameter(description = "Study UUID") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) { - String result = loadflowService.getLoadFlowStatus(nodeUuid); + String result = loadflowService.getLoadFlowStatus(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid)); return result != null ? ResponseEntity.ok().body(result) : ResponseEntity.noContent().build(); } @@ -628,7 +628,7 @@ public ResponseEntity getLoadFlowStatus(@Parameter(description = "Study public ResponseEntity stopLoadFlow(@Parameter(description = "Study uuid") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid, @RequestHeader(HEADER_USER_ID) String userId) { - loadflowService.stopLoadFlow(studyUuid, nodeUuid, userId); + loadflowService.stopLoadFlow(studyUuid, nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), userId); return ResponseEntity.ok().build(); } @@ -641,7 +641,7 @@ public ResponseEntity runShortCircuit( @RequestParam(value = "busId", required = false) Optional busId, @RequestHeader(HEADER_USER_ID) String userId) { studyService.assertIsNodeNotReadOnly(nodeUuid); - studyService.runShortCircuit(studyUuid, nodeUuid, busId, userId); + studyService.runShortCircuit(studyUuid, nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), busId, userId); return ResponseEntity.ok().build(); } @@ -651,7 +651,7 @@ public ResponseEntity runShortCircuit( public ResponseEntity stopShortCircuitAnalysis(@Parameter(description = "Study uuid") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid, @RequestHeader(HEADER_USER_ID) String userId) { - shortCircuitService.stopShortCircuitAnalysis(studyUuid, nodeUuid, userId); + shortCircuitService.stopShortCircuitAnalysis(studyUuid, nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), userId); return ResponseEntity.ok().build(); } @@ -670,7 +670,7 @@ public ResponseEntity getShortCircuitResult(@Parameter(description = "st @Parameter(description = "JSON array of filters") @RequestParam(name = "filters", required = false) String filters, @Parameter(description = "If we wanted the paged version of the results or not") @RequestParam(name = "paged", required = false, defaultValue = "false") boolean paged, Pageable pageable) { - String result = shortCircuitService.getShortCircuitAnalysisResult(nodeUuid, mode, type, filters, paged, pageable); + String result = shortCircuitService.getShortCircuitAnalysisResult(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), mode, type, filters, paged, pageable); return result != null ? ResponseEntity.ok().body(result) : ResponseEntity.noContent().build(); } @@ -683,7 +683,7 @@ public ResponseEntity getShortCircuitResult(@Parameter(description = "st public ResponseEntity getShortCircuitAnalysisStatus(@Parameter(description = "Study UUID") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid, @Parameter(description = "type") @RequestParam(value = "type", required = false, defaultValue = "ALL_BUSES") ShortcircuitAnalysisType type) { - String result = shortCircuitService.getShortCircuitAnalysisStatus(nodeUuid, type); + String result = shortCircuitService.getShortCircuitAnalysisStatus(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), type); return result != null ? ResponseEntity.ok().body(result) : ResponseEntity.noContent().build(); } @@ -698,7 +698,7 @@ public ResponseEntity getShortCircuitAnalysisCsvResult( @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid, @Parameter(description = "type") @RequestParam(value = "type") ShortcircuitAnalysisType type, @Parameter(description = "headersCsv") @RequestBody String headersCsv) { - return ResponseEntity.ok().body(shortCircuitService.getShortCircuitAnalysisCsvResult(nodeUuid, type, headersCsv)); + return ResponseEntity.ok().body(shortCircuitService.getShortCircuitAnalysisCsvResult(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), type, headersCsv)); } @PutMapping(value = "/studies/{studyUuid}/nodes/{nodeUuid}/voltage-init/run") @@ -710,7 +710,7 @@ public ResponseEntity runVoltageInit( @PathVariable("nodeUuid") UUID nodeUuid, @RequestHeader(HEADER_USER_ID) String userId) { studyService.assertIsNodeNotReadOnly(nodeUuid); - studyService.runVoltageInit(studyUuid, nodeUuid, userId); + studyService.runVoltageInit(studyUuid, nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), userId); return ResponseEntity.ok().build(); } @@ -720,7 +720,7 @@ public ResponseEntity runVoltageInit( public ResponseEntity stopVoltageInit(@Parameter(description = "Study uuid") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid, @RequestHeader(HEADER_USER_ID) String userId) { - voltageInitService.stopVoltageInit(studyUuid, nodeUuid, userId); + voltageInitService.stopVoltageInit(studyUuid, nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), userId); return ResponseEntity.ok().build(); } @@ -731,7 +731,7 @@ public ResponseEntity stopVoltageInit(@Parameter(description = "Study uuid @ApiResponse(responseCode = "404", description = "The voltage init has not been found")}) public ResponseEntity getVoltageInitResult(@Parameter(description = "study UUID") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) { - String result = voltageInitService.getVoltageInitResult(nodeUuid); + String result = voltageInitService.getVoltageInitResult(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid)); return result != null ? ResponseEntity.ok().body(result) : ResponseEntity.noContent().build(); } @@ -743,7 +743,7 @@ public ResponseEntity getVoltageInitResult(@Parameter(description = "stu @ApiResponse(responseCode = "404", description = "The voltage init status has not been found")}) public ResponseEntity getVoltageInitStatus(@Parameter(description = "Study UUID") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) { - String result = voltageInitService.getVoltageInitStatus(nodeUuid); + String result = voltageInitService.getVoltageInitStatus(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid)); return result != null ? ResponseEntity.ok().body(result) : ResponseEntity.noContent().build(); } @@ -801,7 +801,7 @@ public ResponseEntity runSecurityAnalysis(@Parameter(description = "studyU @RequestHeader(HEADER_USER_ID) String userId) { List nonNullcontingencyListNames = contingencyListNames != null ? contingencyListNames : Collections.emptyList(); studyService.assertIsNodeNotReadOnly(nodeUuid); - studyService.runSecurityAnalysis(studyUuid, nonNullcontingencyListNames, nodeUuid, userId); + studyService.runSecurityAnalysis(studyUuid, nonNullcontingencyListNames, nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), userId); return ResponseEntity.ok().build(); } @@ -815,7 +815,7 @@ public ResponseEntity getSecurityAnalysisResult(@Parameter(description = @Parameter(description = "result type") @RequestParam(name = "resultType") SecurityAnalysisResultType resultType, @Parameter(description = "JSON array of filters") @RequestParam(name = "filters", required = false) String filters, Pageable pageable) { - String result = securityAnalysisService.getSecurityAnalysisResult(nodeUuid, resultType, filters, pageable); + String result = securityAnalysisService.getSecurityAnalysisResult(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), resultType, filters, pageable); return result != null ? ResponseEntity.ok().body(result) : ResponseEntity.noContent().build(); } @@ -829,7 +829,7 @@ public byte[] getSecurityAnalysisResult(@Parameter(description = "study UUID") @ @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid, @Parameter(description = "result type") @RequestParam(name = "resultType") SecurityAnalysisResultType resultType, @Parameter(description = "Csv translation (JSON)") @RequestBody String csvTranslations) { - return securityAnalysisService.getSecurityAnalysisResultCsv(nodeUuid, resultType, csvTranslations); + return securityAnalysisService.getSecurityAnalysisResultCsv(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), resultType, csvTranslations); } @GetMapping(value = "/studies/{studyUuid}/nodes/{nodeUuid}/contingency-count") @@ -1019,7 +1019,7 @@ public ResponseEntity getNeworkAreaDiagram( @ApiResponse(responseCode = "404", description = "The security analysis status has not been found")}) public ResponseEntity getSecurityAnalysisStatus(@Parameter(description = "Study UUID") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) { - SecurityAnalysisStatus status = securityAnalysisService.getSecurityAnalysisStatus(nodeUuid); + SecurityAnalysisStatus status = securityAnalysisService.getSecurityAnalysisStatus(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid)); return status != null ? ResponseEntity.ok().body(status.name()) : ResponseEntity.noContent().build(); } @@ -1030,7 +1030,7 @@ public ResponseEntity getSecurityAnalysisStatus(@Parameter(description = public ResponseEntity stopSecurityAnalysis(@Parameter(description = "Study uuid") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid, @RequestHeader(HEADER_USER_ID) String userId) { - securityAnalysisService.stopSecurityAnalysis(studyUuid, nodeUuid, userId); + securityAnalysisService.stopSecurityAnalysis(studyUuid, nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), userId); return ResponseEntity.ok().build(); } @@ -1043,7 +1043,7 @@ public ResponseEntity> getParentNodesReport(@Parameter(description @Parameter(description = "The report Type") @RequestParam(name = "reportType") StudyService.ReportType reportType, @Parameter(description = "Severity levels") @RequestParam(name = "severityLevels", required = false) Set severityLevels) { studyService.assertIsStudyAndNodeExist(studyUuid, nodeUuid); - return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(studyService.getParentNodesReport(nodeUuid, nodeOnlyReport, reportType, severityLevels)); + return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(studyService.getParentNodesReport(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), nodeOnlyReport, reportType, severityLevels)); } @GetMapping(value = "/studies/{studyUuid}/nodes/{nodeUuid}/report/{reportId}/logs", produces = MediaType.APPLICATION_JSON_VALUE) @@ -1066,7 +1066,7 @@ public ResponseEntity> getParentNodesReportLogs(@Parameter(descr @Parameter(description = "the message filter") @RequestParam(name = "message", required = false) String messageFilter, @Parameter(description = "Severity levels filter") @RequestParam(name = "severityLevels", required = false) Set severityLevels) { studyService.assertIsStudyAndNodeExist(studyUuid, nodeUuid); - return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(studyService.getParentNodesReportLogs(nodeUuid, messageFilter, severityLevels)); + return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(studyService.getParentNodesReportLogs(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), messageFilter, severityLevels)); } @GetMapping(value = "/svg-component-libraries") @@ -1178,7 +1178,7 @@ public ResponseEntity> searchEquipments( @Parameter(description = "Should search in upstream built node") @RequestParam(value = "inUpstreamBuiltParentNode", required = false, defaultValue = "false") boolean inUpstreamBuiltParentNode, @Parameter(description = "Equipment type") @RequestParam(value = "equipmentType", required = false) String equipmentType) { return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON) - .body(studyService.searchEquipments(studyUuid, nodeUuid, userInput, fieldSelector, equipmentType, inUpstreamBuiltParentNode)); + .body(studyService.searchEquipments(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), userInput, fieldSelector, equipmentType, inUpstreamBuiltParentNode)); } @PostMapping(value = "/studies/{studyUuid}/tree/nodes/{id}") @@ -1186,12 +1186,12 @@ public ResponseEntity> searchEquipments( @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "The node has been added"), @ApiResponse(responseCode = "404", description = "The study or the node not found")}) - public ResponseEntity createNode(@RequestBody AbstractNode node, + public ResponseEntity createNode(@RequestBody NetworkModificationNode node, @Parameter(description = "study uuid") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "parent id of the node created") @PathVariable(name = "id") UUID referenceId, @Parameter(description = "node is inserted before the given node ID") @RequestParam(name = "mode", required = false, defaultValue = "CHILD") InsertMode insertMode, @RequestHeader(HEADER_USER_ID) String userId) { - return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(networkModificationTreeService.createNode(studyUuid, referenceId, node, insertMode, userId)); + return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(studyService.createNode(studyUuid, referenceId, node, insertMode, userId)); } @DeleteMapping(value = "/studies/{studyUuid}/tree/nodes") @@ -1269,7 +1269,7 @@ public ResponseEntity getNetworkModificationSubtree(@Pa @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "the node has been updated"), @ApiResponse(responseCode = "404", description = "The study or the node not found")}) - public ResponseEntity updateNode(@RequestBody AbstractNode node, + public ResponseEntity updateNode(@RequestBody NetworkModificationNode node, @Parameter(description = "study uuid") @PathVariable("studyUuid") UUID studyUuid, @RequestHeader(HEADER_USER_ID) String userId) { networkModificationTreeService.updateNode(studyUuid, node, userId); @@ -1340,7 +1340,7 @@ public ResponseEntity unbuildNode(@Parameter(description = "Study uuid") @ @ApiResponse(responseCode = "404", description = "The study or node doesn't exist")}) public ResponseEntity stopBuild(@Parameter(description = "Study uuid") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) { - studyService.stopBuild(nodeUuid); + studyService.stopBuild(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid)); return ResponseEntity.ok().build(); } @@ -1414,7 +1414,7 @@ public ResponseEntity getSensitivityAnalysisResult( @Parameter(description = "study UUID") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid, @Parameter(description = "results selector") @RequestParam("selector") String selector) { - String result = sensitivityAnalysisService.getSensitivityAnalysisResult(nodeUuid, selector); + String result = sensitivityAnalysisService.getSensitivityAnalysisResult(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), selector); return result != null ? ResponseEntity.ok().body(result) : ResponseEntity.noContent().build(); } @@ -1428,7 +1428,7 @@ public ResponseEntity exportSensitivityResultsAsCsv( @Parameter(description = "study UUID") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid, @RequestBody SensitivityAnalysisCsvFileInfos sensitivityAnalysisCsvFileInfos) { - byte[] result = sensitivityAnalysisService.exportSensitivityResultsAsCsv(nodeUuid, sensitivityAnalysisCsvFileInfos); + byte[] result = sensitivityAnalysisService.exportSensitivityResultsAsCsv(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), sensitivityAnalysisCsvFileInfos); HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); responseHeaders.setContentDispositionFormData("attachment", "sensitivity_results.csv"); @@ -1448,7 +1448,7 @@ public ResponseEntity getSensitivityAnalysisFilterOptions( @Parameter(description = "study UUID") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid, @Parameter(description = "results selector") @RequestParam("selector") String selector) { - String result = sensitivityAnalysisService.getSensitivityResultsFilterOptions(nodeUuid, selector); + String result = sensitivityAnalysisService.getSensitivityResultsFilterOptions(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), selector); return result != null ? ResponseEntity.ok().body(result) : ResponseEntity.noContent().build(); } @@ -1460,7 +1460,7 @@ public ResponseEntity getSensitivityAnalysisFilterOptions( @ApiResponse(responseCode = "404", description = "The sensitivity analysis status has not been found")}) public ResponseEntity getSensitivityAnalysisStatus(@Parameter(description = "Study UUID") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) { - String result = sensitivityAnalysisService.getSensitivityAnalysisStatus(nodeUuid); + String result = sensitivityAnalysisService.getSensitivityAnalysisStatus(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid)); return result != null ? ResponseEntity.ok().body(result) : ResponseEntity.noContent().build(); } @@ -1471,7 +1471,7 @@ public ResponseEntity getSensitivityAnalysisStatus(@Parameter(descriptio public ResponseEntity stopSensitivityAnalysis(@Parameter(description = "Study uuid") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid, @RequestHeader(HEADER_USER_ID) String userId) { - sensitivityAnalysisService.stopSensitivityAnalysis(studyUuid, nodeUuid, userId); + sensitivityAnalysisService.stopSensitivityAnalysis(studyUuid, nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), userId); return ResponseEntity.ok().build(); } @@ -1593,7 +1593,7 @@ public ResponseEntity runDynamicSimulation(@Parameter(description = "study @RequestBody(required = false) DynamicSimulationParametersInfos parameters, @RequestHeader(HEADER_USER_ID) String userId) { studyService.assertIsNodeNotReadOnly(nodeUuid); - studyService.runDynamicSimulation(studyUuid, nodeUuid, parameters, userId); + studyService.runDynamicSimulation(studyUuid, nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), parameters, userId); return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).build(); } @@ -1604,7 +1604,7 @@ public ResponseEntity runDynamicSimulation(@Parameter(description = "study @ApiResponse(responseCode = "404", description = "The dynamic simulation has not been found")}) public ResponseEntity> getDynamicSimulationTimeSeriesMetadata(@Parameter(description = "study UUID") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) { - List result = studyService.getDynamicSimulationTimeSeriesMetadata(nodeUuid); + List result = studyService.getDynamicSimulationTimeSeriesMetadata(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid)); return CollectionUtils.isEmpty(result) ? ResponseEntity.noContent().build() : ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(result); } @@ -1617,7 +1617,7 @@ public ResponseEntity> getDynamicSimulationTimeSer public ResponseEntity> getDynamicSimulationTimeSeriesResult(@Parameter(description = "study UUID") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid, @Parameter(description = "timeSeriesNames") @RequestParam(name = "timeSeriesNames", required = false) List timeSeriesNames) { - List result = studyService.getDynamicSimulationTimeSeries(nodeUuid, timeSeriesNames); + List result = studyService.getDynamicSimulationTimeSeries(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), timeSeriesNames); return CollectionUtils.isEmpty(result) ? ResponseEntity.noContent().build() : ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(result); } @@ -1629,7 +1629,7 @@ public ResponseEntity> getDynamicSimulationTimeSeriesResu @ApiResponse(responseCode = "404", description = "The dynamic simulation has not been found")}) public ResponseEntity> getDynamicSimulationTimelineResult(@Parameter(description = "study UUID") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) { - List result = studyService.getDynamicSimulationTimeline(nodeUuid); + List result = studyService.getDynamicSimulationTimeline(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid)); return CollectionUtils.isEmpty(result) ? ResponseEntity.noContent().build() : ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(result); } @@ -1641,7 +1641,7 @@ public ResponseEntity> getDynamicSimulationTimelineResu @ApiResponse(responseCode = "404", description = "The dynamic simulation has not been found")}) public ResponseEntity getDynamicSimulationStatus(@Parameter(description = "study UUID") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) { - DynamicSimulationStatus result = studyService.getDynamicSimulationStatus(nodeUuid); + DynamicSimulationStatus result = studyService.getDynamicSimulationStatus(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid)); return result != null ? ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(result) : ResponseEntity.noContent().build(); } @@ -1673,7 +1673,7 @@ public ResponseEntity setSecurityAnalysisParametersValues( public ResponseEntity getVoltageInitModifications(@Parameter(description = "Study UUID") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "Node UUID") @PathVariable("nodeUuid") UUID nodeUuid) { studyService.assertIsStudyAndNodeExist(studyUuid, nodeUuid); - return ResponseEntity.ok().contentType(MediaType.TEXT_PLAIN).body(studyService.getVoltageInitModifications(nodeUuid)); + return ResponseEntity.ok().contentType(MediaType.TEXT_PLAIN).body(studyService.getVoltageInitModifications(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid))); } @PutMapping(value = "/studies/{studyUuid}/nodes/{nodeUuid}/voltage-init/modifications", produces = MediaType.APPLICATION_JSON_VALUE) @@ -1754,7 +1754,7 @@ public ResponseEntity getSensitivityAnalysisFactorsCount( @Parameter(description = "Is Injections Set") @RequestParam(name = "isInjectionsSet", required = false) Boolean isInjectionsSet, SensitivityFactorsIdsByGroup factorsIds) { return ResponseEntity.ok().body(sensitivityAnalysisService.getSensitivityAnalysisFactorsCount(networkStoreService.getNetworkUuid(studyUuid), - networkModificationTreeService.getVariantId(nodeUuid), factorsIds, isInjectionsSet)); + networkModificationTreeService.getVariantId(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid)), factorsIds, isInjectionsSet)); } @PutMapping(value = "/studies/{studyUuid}/loadflow/invalidate-status") @@ -1794,7 +1794,7 @@ public ResponseEntity runNonEvacuatedEnergy(@Parameter(description = "stud @ApiResponse(responseCode = "404", description = "The sensitivity analysis non evacuated energy has not been found")}) public ResponseEntity getNonEvacuatedEnergyResult(@Parameter(description = "study UUID") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) { - String result = nonEvacuatedEnergyService.getNonEvacuatedEnergyResult(nodeUuid); + String result = nonEvacuatedEnergyService.getNonEvacuatedEnergyResult(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid)); return result != null ? ResponseEntity.ok().body(result) : ResponseEntity.noContent().build(); } @@ -1806,7 +1806,7 @@ public ResponseEntity getNonEvacuatedEnergyResult(@Parameter(description @ApiResponse(responseCode = "404", description = "The sensitivity analysis status non evacuated energy has not been found")}) public ResponseEntity getNonEvacuatedEnergyStatus(@Parameter(description = "Study UUID") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) { - String result = nonEvacuatedEnergyService.getNonEvacuatedEnergyStatus(nodeUuid); + String result = nonEvacuatedEnergyService.getNonEvacuatedEnergyStatus(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid)); return result != null ? ResponseEntity.ok().body(result) : ResponseEntity.noContent().build(); } @@ -1817,7 +1817,7 @@ public ResponseEntity getNonEvacuatedEnergyStatus(@Parameter(description public ResponseEntity stopNonEvacuatedEnergy(@Parameter(description = "Study uuid") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid, @RequestHeader(HEADER_USER_ID) String userId) { - nonEvacuatedEnergyService.stopNonEvacuatedEnergy(studyUuid, nodeUuid, userId); + nonEvacuatedEnergyService.stopNonEvacuatedEnergy(studyUuid, nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), userId); return ResponseEntity.ok().build(); } @@ -1921,7 +1921,7 @@ public ResponseEntity runStateEstimation(@Parameter(description = "studyUu @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid, @RequestHeader(HEADER_USER_ID) String userId) { studyService.assertIsNodeNotReadOnly(nodeUuid); - studyService.runStateEstimation(studyUuid, nodeUuid, userId); + studyService.runStateEstimation(studyUuid, nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid), userId); return ResponseEntity.ok().build(); } @@ -1932,7 +1932,7 @@ public ResponseEntity runStateEstimation(@Parameter(description = "studyUu @ApiResponse(responseCode = "404", description = "The state estimation has not been found")}) public ResponseEntity getStateEstimationResult(@Parameter(description = "study UUID") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) { - String result = stateEstimationService.getStateEstimationResult(nodeUuid); + String result = stateEstimationService.getStateEstimationResult(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid)); return result != null ? ResponseEntity.ok().body(result) : ResponseEntity.noContent().build(); } @@ -1944,7 +1944,7 @@ public ResponseEntity getStateEstimationResult(@Parameter(description = @ApiResponse(responseCode = "404", description = "The state estimation status has not been found")}) public ResponseEntity getStateEstimationStatus(@Parameter(description = "Study UUID") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) { - String status = stateEstimationService.getStateEstimationStatus(nodeUuid); + String status = stateEstimationService.getStateEstimationStatus(nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid)); return status != null ? ResponseEntity.ok().body(status) : ResponseEntity.noContent().build(); } @@ -1953,7 +1953,7 @@ public ResponseEntity getStateEstimationStatus(@Parameter(description = @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The state estimation has been stopped")}) public ResponseEntity stopStateEstimation(@Parameter(description = "Study uuid") @PathVariable("studyUuid") UUID studyUuid, @Parameter(description = "nodeUuid") @PathVariable("nodeUuid") UUID nodeUuid) { - stateEstimationService.stopStateEstimation(studyUuid, nodeUuid); + stateEstimationService.stopStateEstimation(studyUuid, nodeUuid, studyService.getStudyFirstRootNetworkUuid(studyUuid)); return ResponseEntity.ok().build(); } } diff --git a/src/main/java/org/gridsuite/study/server/StudyException.java b/src/main/java/org/gridsuite/study/server/StudyException.java index 6479f74cf..d8bdc1c18 100644 --- a/src/main/java/org/gridsuite/study/server/StudyException.java +++ b/src/main/java/org/gridsuite/study/server/StudyException.java @@ -114,6 +114,7 @@ public enum Type { STATE_ESTIMATION_NOT_FOUND, STATE_ESTIMATION_ERROR, MAX_NODE_BUILDS_EXCEEDED, + ROOTNETWORK_NOT_FOUND } private final Type type; diff --git a/src/main/java/org/gridsuite/study/server/dto/CaseInfos.java b/src/main/java/org/gridsuite/study/server/dto/CaseInfos.java new file mode 100644 index 000000000..7ceb713bc --- /dev/null +++ b/src/main/java/org/gridsuite/study/server/dto/CaseInfos.java @@ -0,0 +1,27 @@ +/** + * 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.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.UUID; + +/** + * @author Slimane amar @@ -34,71 +25,8 @@ protected AbstractNodeRepositoryProxy(R nodeInfoRepository) { this.nodeInfoRepository = nodeInfoRepository; } - public abstract T toEntity(AbstractNode node); - public abstract U toDto(T node); - public String getVariantId(AbstractNode node) { - return null; - } - - public UUID getModificationGroupUuid(AbstractNode node) { - return null; - } - - public void updateComputationResultUuid(AbstractNode node, UUID resultUuid, ComputationType computationType) { - } - - public void updateComputationReportUuid(AbstractNode node, UUID reportUuid, ComputationType computationType) { - } - - public void setModificationReports(AbstractNode node, Map reports) { - } - - public void setComputationsReports(AbstractNode node, Map reports) { - } - - public NodeBuildStatus getNodeBuildStatus(AbstractNode node) { - return NodeBuildStatus.from(BuildStatus.NOT_BUILT); - } - - /** - * @param node fetched network modification node - * @param computationType type of the fetched computation - * @return UUID of the computation of this type, done on this node - */ - public UUID getComputationResultUuid(AbstractNode node, ComputationType computationType) { - return null; - } - - public Map getComputationReports(AbstractNode node) { - return new HashMap<>(); - } - - public Map getModificationReports(AbstractNode node) { - return new HashMap<>(); - } - - public UUID getReportUuid(AbstractNode node) { - return null; - } - - public void updateNodeBuildStatus(AbstractNode node, NodeBuildStatus nodeBuildStatus, List changedNodes) { - } - - public void invalidateNodeBuildStatus(AbstractNode node, List changedNodes) { - } - - public void createNodeInfo(AbstractNode nodeInfo) { - if (nodeInfo.getType() == NodeType.NETWORK_MODIFICATION) { - NetworkModificationNode node = (NetworkModificationNode) nodeInfo; - if (node.getModificationReports() == null) { - node.setModificationReports(Map.of(node.getId(), UUID.randomUUID())); - } - } - nodeInfoRepository.save(toEntity(nodeInfo)); - } - public void deleteByNodeId(UUID id) { nodeInfoRepository.deleteById(id); } @@ -115,26 +43,8 @@ protected U completeNodeInfo(AbstractNodeInfoEntity nodeInfoEntity, U node) { return node; } - protected T completeEntityNodeInfo(AbstractNode node, T entity) { - entity.setIdNode(node.getId()); - entity.setName(node.getName()); - entity.setDescription(node.getDescription()); - entity.setReadOnly(node.getReadOnly()); - return entity; - } - - public void updateNode(AbstractNode node, String... authorizedNullProperties) { - U persistedNode = getNode(node.getId()); - /* using only DTO values not jpa Entity */ - PropertyUtils.copyNonNullProperties(node, persistedNode, authorizedNullProperties); - - T entity = toEntity(persistedNode); - entity.markNotNew(); - nodeInfoRepository.save(entity); - } - - public Map getAll(Collection ids) { - return nodeInfoRepository.findAllById(ids).stream().map(this::toDto).collect(Collectors.toMap(U::getId, Function.identity())); + public List getAll(Collection ids) { + return nodeInfoRepository.findAllById(ids).stream().map(this::toDto).toList(); } public List getAllInOrder(List ids) { @@ -147,67 +57,7 @@ public void deleteAll(Set collect) { nodeInfoRepository.deleteByIdNodeIn(collect); } - public String getVariantId(UUID nodeUuid) { - return getVariantId(getNode(nodeUuid)); - } - - public UUID getModificationGroupUuid(UUID nodeUuid) { - return getModificationGroupUuid(getNode(nodeUuid)); - } - - public void updateComputationResultUuid(UUID nodeUuid, UUID computationResultUuid, ComputationType computationType) { - updateComputationResultUuid(getNode(nodeUuid), computationResultUuid, computationType); - } - - public UUID getComputationResultUuid(UUID nodeUuid, ComputationType computationType) { - return getComputationResultUuid(getNode(nodeUuid), computationType); - } - - public Map getComputationReports(UUID nodeUuid) { - return getComputationReports(getNode(nodeUuid)); - } - - public Map getModificationReports(UUID nodeUuid) { - return getModificationReports(getNode(nodeUuid)); - } - - public UUID getReportUuid(UUID nodeUuid) { - return getReportUuid(getNode(nodeUuid)); - } - - public void updateComputationReportUuid(UUID nodeUuid, UUID reportUuid, ComputationType computationType) { - updateComputationReportUuid(getNode(nodeUuid), reportUuid, computationType); - } - - public void setModificationReports(UUID nodeUuid, Map reports) { - setModificationReports(getNode(nodeUuid), reports); - } - - public void setComputationsReports(UUID nodeUuid, Map reports) { - setComputationsReports(getNode(nodeUuid), reports); - } - - public void updateNodeBuildStatus(UUID nodeUuid, NodeBuildStatus nodeBuildStatus, List changedNodes) { - updateNodeBuildStatus(getNode(nodeUuid), nodeBuildStatus, changedNodes); - } - - public NodeBuildStatus getNodeBuildStatus(UUID nodeUuid) { - return getNodeBuildStatus(getNode(nodeUuid)); - } - - public void invalidateNodeBuildStatus(UUID nodeUuid, List changedNodes) { - invalidateNodeBuildStatus(getNode(nodeUuid), changedNodes); - } - public Boolean isReadOnly(UUID nodeUuid) { - return getNode(nodeUuid).getReadOnly(); - } - - public NodeModificationInfos getNodeModificationInfos(AbstractNode node) { - return null; - } - - public NodeModificationInfos getNodeModificationInfos(UUID nodeUuid) { - return getNodeModificationInfos(getNode(nodeUuid)); + return nodeInfoRepository.findById(nodeUuid).orElseThrow(() -> new StudyException(StudyException.Type.NODE_NOT_FOUND)).getReadOnly(); } } diff --git a/src/main/java/org/gridsuite/study/server/networkmodificationtree/NetworkModificationNodeInfoRepositoryProxy.java b/src/main/java/org/gridsuite/study/server/networkmodificationtree/NetworkModificationNodeInfoRepositoryProxy.java index 1e48346ad..534905a25 100644 --- a/src/main/java/org/gridsuite/study/server/networkmodificationtree/NetworkModificationNodeInfoRepositoryProxy.java +++ b/src/main/java/org/gridsuite/study/server/networkmodificationtree/NetworkModificationNodeInfoRepositoryProxy.java @@ -7,20 +7,11 @@ package org.gridsuite.study.server.networkmodificationtree; -import org.gridsuite.study.server.dto.ComputationType; -import org.gridsuite.study.server.dto.NodeModificationInfos; -import org.gridsuite.study.server.networkmodificationtree.dto.AbstractNode; -import org.gridsuite.study.server.networkmodificationtree.dto.BuildStatus; -import org.gridsuite.study.server.networkmodificationtree.dto.NetworkModificationNode; -import org.gridsuite.study.server.networkmodificationtree.dto.NodeBuildStatus; +import org.gridsuite.study.server.networkmodificationtree.dto.*; import org.gridsuite.study.server.networkmodificationtree.entities.NetworkModificationNodeInfoEntity; +import org.gridsuite.study.server.networkmodificationtree.entities.RootNetworkNodeInfoEntity; import org.gridsuite.study.server.repository.networkmodificationtree.NetworkModificationNodeInfoRepository; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.UUID; - /** * @author Jacques Borsenberger getComputationReports(AbstractNode node) { - return ((NetworkModificationNode) node).getComputationsReports(); - } - - @Override - public Map getModificationReports(AbstractNode node) { - return ((NetworkModificationNode) node).getModificationReports(); - } - - @Override - public UUID getReportUuid(AbstractNode node) { - return ((NetworkModificationNode) node).getModificationReports().get(node.getId()); - } - - @Override - public void setModificationReports(AbstractNode node, Map modificationReports) { - ((NetworkModificationNode) node).setModificationReports(modificationReports); - updateNode(node); - } - - @Override - public void setComputationsReports(AbstractNode node, Map computationReports) { - ((NetworkModificationNode) node).setComputationsReports(computationReports); - updateNode(node); - } - - @Override - public void updateComputationResultUuid(AbstractNode node, UUID computationUuid, ComputationType computationType) { - NetworkModificationNode modificationNode = (NetworkModificationNode) node; - switch (computationType) { - case LOAD_FLOW -> modificationNode.setLoadFlowResultUuid(computationUuid); - case SECURITY_ANALYSIS -> modificationNode.setSecurityAnalysisResultUuid(computationUuid); - case SENSITIVITY_ANALYSIS -> modificationNode.setSensitivityAnalysisResultUuid(computationUuid); - case NON_EVACUATED_ENERGY_ANALYSIS -> modificationNode.setNonEvacuatedEnergyResultUuid(computationUuid); - case SHORT_CIRCUIT -> modificationNode.setShortCircuitAnalysisResultUuid(computationUuid); - case SHORT_CIRCUIT_ONE_BUS -> modificationNode.setOneBusShortCircuitAnalysisResultUuid(computationUuid); - case VOLTAGE_INITIALIZATION -> modificationNode.setVoltageInitResultUuid(computationUuid); - case DYNAMIC_SIMULATION -> modificationNode.setDynamicSimulationResultUuid(computationUuid); - case STATE_ESTIMATION -> modificationNode.setStateEstimationResultUuid(computationUuid); - } - updateNode(modificationNode, computationType.getResultUuidLabel()); - } - - @Override - public UUID getComputationResultUuid(AbstractNode node, ComputationType computationType) { - return switch (computationType) { - case LOAD_FLOW -> ((NetworkModificationNode) node).getLoadFlowResultUuid(); - case SECURITY_ANALYSIS -> ((NetworkModificationNode) node).getSecurityAnalysisResultUuid(); - case SENSITIVITY_ANALYSIS -> ((NetworkModificationNode) node).getSensitivityAnalysisResultUuid(); - case NON_EVACUATED_ENERGY_ANALYSIS -> ((NetworkModificationNode) node).getNonEvacuatedEnergyResultUuid(); - case SHORT_CIRCUIT -> ((NetworkModificationNode) node).getShortCircuitAnalysisResultUuid(); - case SHORT_CIRCUIT_ONE_BUS -> ((NetworkModificationNode) node).getOneBusShortCircuitAnalysisResultUuid(); - case VOLTAGE_INITIALIZATION -> ((NetworkModificationNode) node).getVoltageInitResultUuid(); - case DYNAMIC_SIMULATION -> ((NetworkModificationNode) node).getDynamicSimulationResultUuid(); - case STATE_ESTIMATION -> ((NetworkModificationNode) node).getStateEstimationResultUuid(); - }; - } - - private void updateNode(NetworkModificationNode node, List changedNodes) { - updateNode(node); - changedNodes.add(node.getId()); - } - - @Override - public void updateNodeBuildStatus(AbstractNode node, NodeBuildStatus nodeBuildStatus, List changedNodes) { - NetworkModificationNode modificationNode = (NetworkModificationNode) node; - modificationNode.setNodeBuildStatus(nodeBuildStatus); - updateNode(modificationNode, changedNodes); - } - - @Override - public NodeBuildStatus getNodeBuildStatus(AbstractNode node) { - return ((NetworkModificationNode) node).getNodeBuildStatus(); - } - - @Override - public void invalidateNodeBuildStatus(AbstractNode node, List changedNodes) { - NetworkModificationNode modificationNode = (NetworkModificationNode) node; - if (!modificationNode.getNodeBuildStatus().isBuilt()) { - return; - } - - modificationNode.setNodeBuildStatus(NodeBuildStatus.from(BuildStatus.NOT_BUILT)); - modificationNode.setVariantId(UUID.randomUUID().toString()); - modificationNode.setModificationReports(Map.of(modificationNode.getId(), UUID.randomUUID())); - updateNode(modificationNode, changedNodes); - } - - @Override - public NodeModificationInfos getNodeModificationInfos(AbstractNode node) { - NetworkModificationNode networkModificationNode = (NetworkModificationNode) node; - return NodeModificationInfos.builder() - .id(networkModificationNode.getId()) - .modificationGroupUuid(networkModificationNode.getModificationGroupUuid()) - .variantId(networkModificationNode.getVariantId()) - .loadFlowUuid(networkModificationNode.getLoadFlowResultUuid()) - .securityAnalysisUuid(networkModificationNode.getSecurityAnalysisResultUuid()) - .sensitivityAnalysisUuid(networkModificationNode.getSensitivityAnalysisResultUuid()) - .nonEvacuatedEnergyUuid(networkModificationNode.getNonEvacuatedEnergyResultUuid()) - .shortCircuitAnalysisUuid(networkModificationNode.getShortCircuitAnalysisResultUuid()) - .oneBusShortCircuitAnalysisUuid(networkModificationNode.getOneBusShortCircuitAnalysisResultUuid()) - .voltageInitUuid(networkModificationNode.getVoltageInitResultUuid()) - .dynamicSimulationUuid(networkModificationNode.getDynamicSimulationResultUuid()) - .stateEstimationUuid(networkModificationNode.getStateEstimationResultUuid()) - .reportUuid(networkModificationNode.getModificationReports().get(networkModificationNode.getId())) - .nodeType(networkModificationNode.getType()) - .build(); + @SuppressWarnings("unused") + RootNetworkNodeInfoEntity rootNetworkNodeStatusEntity = node.getFirstRootNetworkNodeInfosEntity(); + NetworkModificationNode networkModificationNode = NetworkModificationNode.builder().modificationGroupUuid(node.getModificationGroupUuid()).build(); + networkModificationNode.completeDtoFromRootNetworkNodeInfo(rootNetworkNodeStatusEntity); + return completeNodeInfo(node, networkModificationNode); } } diff --git a/src/main/java/org/gridsuite/study/server/networkmodificationtree/RootNodeInfoRepositoryProxy.java b/src/main/java/org/gridsuite/study/server/networkmodificationtree/RootNodeInfoRepositoryProxy.java index d647ec85a..8020b43d5 100644 --- a/src/main/java/org/gridsuite/study/server/networkmodificationtree/RootNodeInfoRepositoryProxy.java +++ b/src/main/java/org/gridsuite/study/server/networkmodificationtree/RootNodeInfoRepositoryProxy.java @@ -7,10 +7,6 @@ package org.gridsuite.study.server.networkmodificationtree; -import java.util.UUID; - -import org.gridsuite.study.server.dto.NodeModificationInfos; -import org.gridsuite.study.server.networkmodificationtree.dto.AbstractNode; import org.gridsuite.study.server.networkmodificationtree.dto.RootNode; import org.gridsuite.study.server.networkmodificationtree.entities.RootNodeInfoEntity; import org.gridsuite.study.server.repository.networkmodificationtree.RootNodeInfoRepository; @@ -23,36 +19,8 @@ public RootNodeInfoRepositoryProxy(RootNodeInfoRepository rootNodeInfoRepository super(rootNodeInfoRepository); } - @Override - public RootNodeInfoEntity toEntity(AbstractNode node) { - var rootNodeInfoEntity = new RootNodeInfoEntity(); - rootNodeInfoEntity.setReportUuid(((RootNode) node).getReportUuid()); - return completeEntityNodeInfo(node, rootNodeInfoEntity); - } - @Override public RootNode toDto(RootNodeInfoEntity node) { - return completeNodeInfo(node, new RootNode(null, node.getReportUuid())); - } - - @Override - public String getVariantId(AbstractNode node) { - return ""; // we will use the network initial variant - } - - @Override - public NodeModificationInfos getNodeModificationInfos(AbstractNode node) { - RootNode rootNode = (RootNode) node; - return NodeModificationInfos.builder() - .id(rootNode.getId()) - .variantId("") // we will use the network initial variant - .reportUuid(rootNode.getReportUuid()) - .nodeType(rootNode.getType()) - .build(); - } - - @Override - public UUID getReportUuid(AbstractNode node) { - return ((RootNode) node).getReportUuid(); + return completeNodeInfo(node, new RootNode(null, null)); } } diff --git a/src/main/java/org/gridsuite/study/server/networkmodificationtree/dto/NetworkModificationNode.java b/src/main/java/org/gridsuite/study/server/networkmodificationtree/dto/NetworkModificationNode.java index 384a191d1..e5f1a4735 100644 --- a/src/main/java/org/gridsuite/study/server/networkmodificationtree/dto/NetworkModificationNode.java +++ b/src/main/java/org/gridsuite/study/server/networkmodificationtree/dto/NetworkModificationNode.java @@ -10,6 +10,7 @@ import lombok.*; import lombok.experimental.SuperBuilder; import org.gridsuite.study.server.networkmodificationtree.entities.NodeType; +import org.gridsuite.study.server.networkmodificationtree.entities.RootNetworkNodeInfoEntity; import java.util.Map; import java.util.UUID; @@ -51,6 +52,22 @@ public class NetworkModificationNode extends AbstractNode { private NodeBuildStatus nodeBuildStatus; + //TODO: temporary, used to keep nodeDTO identical since we don't export rootNetworks in APIs yet, once rootNetworks are exported, result uuid won't be stored in nodeDto + public void completeDtoFromRootNetworkNodeInfo(RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity) { + this.setLoadFlowResultUuid(rootNetworkNodeInfoEntity.getLoadFlowResultUuid()); + this.setShortCircuitAnalysisResultUuid(rootNetworkNodeInfoEntity.getShortCircuitAnalysisResultUuid()); + this.setOneBusShortCircuitAnalysisResultUuid(rootNetworkNodeInfoEntity.getOneBusShortCircuitAnalysisResultUuid()); + this.setVoltageInitResultUuid(rootNetworkNodeInfoEntity.getVoltageInitResultUuid()); + this.setSecurityAnalysisResultUuid(rootNetworkNodeInfoEntity.getSecurityAnalysisResultUuid()); + this.setSensitivityAnalysisResultUuid(rootNetworkNodeInfoEntity.getSensitivityAnalysisResultUuid()); + this.setNonEvacuatedEnergyResultUuid(rootNetworkNodeInfoEntity.getNonEvacuatedEnergyResultUuid()); + this.setDynamicSimulationResultUuid(rootNetworkNodeInfoEntity.getDynamicSimulationResultUuid()); + this.setStateEstimationResultUuid(rootNetworkNodeInfoEntity.getStateEstimationResultUuid()); + this.setNodeBuildStatus(rootNetworkNodeInfoEntity.getNodeBuildStatus().toDto()); + this.setComputationsReports(rootNetworkNodeInfoEntity.getComputationReports()); + this.setModificationReports(rootNetworkNodeInfoEntity.getModificationReports()); + } + private Map computationsReports; private Map modificationReports; diff --git a/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/AbstractNodeInfoEntity.java b/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/AbstractNodeInfoEntity.java index 84a6d9381..388be9482 100644 --- a/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/AbstractNodeInfoEntity.java +++ b/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/AbstractNodeInfoEntity.java @@ -7,17 +7,13 @@ package org.gridsuite.study.server.networkmodificationtree.entities; +import jakarta.persistence.*; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import lombok.experimental.SuperBuilder; import org.gridsuite.study.server.repository.AbstractManuallyAssignedIdentifierEntity; -import jakarta.persistence.Column; -import jakarta.persistence.FetchType; -import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.MappedSuperclass; -import jakarta.persistence.OneToOne; import java.util.UUID; /** @@ -27,6 +23,7 @@ @Getter @Setter @MappedSuperclass +@SuperBuilder public abstract class AbstractNodeInfoEntity extends AbstractManuallyAssignedIdentifierEntity { @Id diff --git a/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/NetworkModificationNodeInfoEntity.java b/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/NetworkModificationNodeInfoEntity.java index 2ed3ae939..d3783fe32 100644 --- a/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/NetworkModificationNodeInfoEntity.java +++ b/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/NetworkModificationNodeInfoEntity.java @@ -8,12 +8,11 @@ package org.gridsuite.study.server.networkmodificationtree.entities; import jakarta.persistence.*; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; +import lombok.*; +import lombok.experimental.SuperBuilder; -import java.util.Map; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; /** @@ -24,58 +23,29 @@ @Getter @Setter @Entity -@Table(name = "NetworkModificationNodeInfo ") +@SuperBuilder +@Table(name = "NetworkModificationNodeInfo") public class NetworkModificationNodeInfoEntity extends AbstractNodeInfoEntity { @Column private UUID modificationGroupUuid; - @Column - private String variantId; - - @Column(name = "shortCircuitAnalysisResultUuid") - private UUID shortCircuitAnalysisResultUuid; - - @Column(name = "oneBusShortCircuitAnalysisResultUuid") - private UUID oneBusShortCircuitAnalysisResultUuid; - - @Column(name = "loadflowResultUuid") - private UUID loadFlowResultUuid; - - @Column(name = "voltageInitResultUuid") - private UUID voltageInitResultUuid; - - @Column(name = "securityAnalysisResultUuid") - private UUID securityAnalysisResultUuid; - - @Column(name = "sensitivityAnalysisResultUuid") - private UUID sensitivityAnalysisResultUuid; - - @Column(name = "nonEvacuatedEnergyResultUuid") - private UUID nonEvacuatedEnergyResultUuid; - - @Column(name = "dynamicSimulationResultUuid") - private UUID dynamicSimulationResultUuid; - - @Column(name = "stateEstimationResultUuid") - private UUID stateEstimationResultUuid; - - @Embedded - @AttributeOverrides(value = { - @AttributeOverride(name = "localBuildStatus", column = @Column(name = "localBuildStatus", nullable = false)), - @AttributeOverride(name = "globalBuildStatus", column = @Column(name = "globalBuildStatus", nullable = false)) - }) - private NodeBuildStatusEmbeddable nodeBuildStatus; - - @ElementCollection - @CollectionTable(name = "computationReports", - indexes = {@Index(name = "networkModificationNodeInfoEntity_computationReports_idx1", columnList = "network_modification_node_info_entity_id_node")}, - foreignKey = @ForeignKey(name = "networkModificationNodeInfoEntity_computationReports_fk1")) - private Map computationReports; - - @ElementCollection - @CollectionTable(name = "modificationReports", - indexes = {@Index(name = "networkModificationNodeInfoEntity_modificationReports_idx1", columnList = "network_modification_node_info_entity_id_node")}, - foreignKey = @ForeignKey(name = "networkModificationNodeInfoEntity_modificationReports_fk1")) - private Map modificationReports; + @OneToMany(orphanRemoval = true, mappedBy = "nodeInfo", cascade = CascadeType.ALL) + protected List rootNetworkNodeInfos; + + //TODO temporary, for now we are only working with one root network by study + public RootNetworkNodeInfoEntity getFirstRootNetworkNodeInfosEntity() { + if (rootNetworkNodeInfos == null || rootNetworkNodeInfos.isEmpty()) { + return null; + } + return rootNetworkNodeInfos.get(0); + } + + public void addRootNetworkNodeInfo(RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity) { + if (rootNetworkNodeInfos == null) { + rootNetworkNodeInfos = new ArrayList<>(); + } + rootNetworkNodeInfoEntity.setNodeInfo(this); + rootNetworkNodeInfos.add(rootNetworkNodeInfoEntity); + } } diff --git a/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/NodeBuildStatusEmbeddable.java b/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/NodeBuildStatusEmbeddable.java index ae4c0194e..839fe22b0 100644 --- a/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/NodeBuildStatusEmbeddable.java +++ b/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/NodeBuildStatusEmbeddable.java @@ -6,9 +6,7 @@ */ package org.gridsuite.study.server.networkmodificationtree.entities; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; import org.gridsuite.study.server.networkmodificationtree.dto.BuildStatus; import org.gridsuite.study.server.networkmodificationtree.dto.NodeBuildStatus; @@ -23,7 +21,9 @@ @Getter @AllArgsConstructor @NoArgsConstructor +@Builder @Embeddable +@EqualsAndHashCode public class NodeBuildStatusEmbeddable { @Column(name = "buildStatusLocal", nullable = false) @@ -37,4 +37,11 @@ public class NodeBuildStatusEmbeddable { public NodeBuildStatus toDto() { return NodeBuildStatus.from(localBuildStatus, globalBuildStatus); } + + public static NodeBuildStatusEmbeddable from(BuildStatus buildStatus) { + return NodeBuildStatusEmbeddable.builder() + .localBuildStatus(buildStatus) + .globalBuildStatus(buildStatus) + .build(); + } } diff --git a/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/RootNetworkNodeInfoEntity.java b/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/RootNetworkNodeInfoEntity.java new file mode 100644 index 000000000..7863e6d12 --- /dev/null +++ b/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/RootNetworkNodeInfoEntity.java @@ -0,0 +1,98 @@ +/* + * 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.networkmodificationtree.entities; + +import jakarta.persistence.*; +import lombok.*; +import lombok.experimental.SuperBuilder; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkEntity; + +import java.util.Map; +import java.util.UUID; + +/** + * @author Le Saulnier Kevin + */ +@NoArgsConstructor +@Getter +@Setter +@Entity +@SuperBuilder +@Table(name = "RootNetworkNodeInfo", + indexes = { + @Index(name = "rootNetworkNodeEntity_rootNetworkId_idx", columnList = "root_network_id"), + @Index(name = "rootNetworkNodeEntity_nodeId_idx", columnList = "node_info_id"), + }) +public class RootNetworkNodeInfoEntity { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id") + private UUID id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "rootNetworkId", + referencedColumnName = "id", nullable = false, + foreignKey = @ForeignKey(name = "rootNetworkNode_rootNetwork_id_fk_constraint")) + private RootNetworkEntity rootNetwork; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "nodeInfoId", + referencedColumnName = "idNode", nullable = false, + foreignKey = @ForeignKey(name = "rootNetworkNode_node_id_fk_constraint")) + private NetworkModificationNodeInfoEntity nodeInfo; + + @Column + private String variantId; + + @ElementCollection + @CollectionTable(name = "computationReports", + indexes = {@Index(name = "root_network_node_info_entity_computationReports_idx1", columnList = "root_network_node_info_entity_id")}, + foreignKey = @ForeignKey(name = "rootNetworkNodeInfoEntity_computationReports_fk1")) + private Map computationReports; + + @ElementCollection + @CollectionTable(name = "modificationReports", + indexes = {@Index(name = "root_network_node_info_entity_modificationReports_idx1", columnList = "root_network_node_info_entity_id")}, + foreignKey = @ForeignKey(name = "rootNetworkNodeInfoEntity_modificationReports_fk1")) + private Map modificationReports; + + @Column(name = "shortCircuitAnalysisResultUuid") + private UUID shortCircuitAnalysisResultUuid; + + @Column(name = "oneBusShortCircuitAnalysisResultUuid") + private UUID oneBusShortCircuitAnalysisResultUuid; + + @Column(name = "loadflowResultUuid") + private UUID loadFlowResultUuid; + + @Column(name = "voltageInitResultUuid") + private UUID voltageInitResultUuid; + + @Column(name = "securityAnalysisResultUuid") + private UUID securityAnalysisResultUuid; + + @Column(name = "sensitivityAnalysisResultUuid") + private UUID sensitivityAnalysisResultUuid; + + @Column(name = "nonEvacuatedEnergyResultUuid") + private UUID nonEvacuatedEnergyResultUuid; + + @Column(name = "dynamicSimulationResultUuid") + private UUID dynamicSimulationResultUuid; + + @Column(name = "stateEstimationResultUuid") + private UUID stateEstimationResultUuid; + + @Embedded + @AttributeOverrides(value = { + @AttributeOverride(name = "localBuildStatus", column = @Column(name = "localBuildStatus", nullable = false)), + @AttributeOverride(name = "globalBuildStatus", column = @Column(name = "globalBuildStatus", nullable = false)) + }) + private NodeBuildStatusEmbeddable nodeBuildStatus; +} diff --git a/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/RootNodeInfoEntity.java b/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/RootNodeInfoEntity.java index f2d7323c2..c128778f0 100644 --- a/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/RootNodeInfoEntity.java +++ b/src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/RootNodeInfoEntity.java @@ -7,15 +7,12 @@ package org.gridsuite.study.server.networkmodificationtree.entities; +import jakarta.persistence.*; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import java.util.UUID; - -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.Table; +import lombok.experimental.SuperBuilder; /** * @author Jacques Borsenberger @@ -24,8 +21,6 @@ @Getter @Setter @Entity +@SuperBuilder @Table(name = "RootNodeInfo") -public class RootNodeInfoEntity extends AbstractNodeInfoEntity { - @Column - private UUID reportUuid; -} +public class RootNodeInfoEntity extends AbstractNodeInfoEntity { } diff --git a/src/main/java/org/gridsuite/study/server/repository/AbstractManuallyAssignedIdentifierEntity.java b/src/main/java/org/gridsuite/study/server/repository/AbstractManuallyAssignedIdentifierEntity.java index f7065af3a..a3249666d 100644 --- a/src/main/java/org/gridsuite/study/server/repository/AbstractManuallyAssignedIdentifierEntity.java +++ b/src/main/java/org/gridsuite/study/server/repository/AbstractManuallyAssignedIdentifierEntity.java @@ -11,6 +11,8 @@ import jakarta.persistence.PrePersist; import jakarta.persistence.Transient; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; import org.springframework.data.domain.Persistable; /** @@ -19,6 +21,8 @@ // Official documentation: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.entity-persistence.saving-entites.strategies @MappedSuperclass +@NoArgsConstructor +@SuperBuilder public abstract class AbstractManuallyAssignedIdentifierEntity implements Persistable { @Transient diff --git a/src/main/java/org/gridsuite/study/server/repository/StudyEntity.java b/src/main/java/org/gridsuite/study/server/repository/StudyEntity.java index 788772071..63b251fbb 100644 --- a/src/main/java/org/gridsuite/study/server/repository/StudyEntity.java +++ b/src/main/java/org/gridsuite/study/server/repository/StudyEntity.java @@ -10,8 +10,11 @@ import lombok.*; import org.gridsuite.study.server.dto.StudyIndexationStatus; import org.gridsuite.study.server.repository.nonevacuatedenergy.NonEvacuatedEnergyParametersEntity; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkEntity; import org.gridsuite.study.server.repository.voltageinit.StudyVoltageInitParametersEntity; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -32,20 +35,8 @@ public class StudyEntity extends AbstractManuallyAssignedIdentifierEntity @Column(name = "id") private UUID id; - @Column(name = "networkUuid", nullable = false) - private UUID networkUuid; - - @Column(name = "networkId", nullable = false) - private String networkId; - - @Column(name = "caseFormat", nullable = false) - private String caseFormat; - - @Column(name = "caseUuid", nullable = false) - private UUID caseUuid; - - @Column(name = "caseName", nullable = false) - private String caseName; + @OneToMany(mappedBy = "study", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) + private List rootNetworks; /** * @deprecated to remove when the data is migrated into the loadflow-server @@ -88,10 +79,10 @@ public class StudyEntity extends AbstractManuallyAssignedIdentifierEntity @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) @JoinColumn(name = "dynamicSimulationParametersEntity_id", - referencedColumnName = "id", - foreignKey = @ForeignKey( - name = "dynamicSimulationParameters_id_fk" - )) + referencedColumnName = "id", + foreignKey = @ForeignKey( + name = "dynamicSimulationParameters_id_fk" + )) private DynamicSimulationParametersEntity dynamicSimulationParameters; @Column(name = "voltageInitParametersUuid") @@ -113,8 +104,8 @@ public class StudyEntity extends AbstractManuallyAssignedIdentifierEntity @ElementCollection @CollectionTable(name = "importParameters", - indexes = {@Index(name = "studyEntity_importParameters_idx1", columnList = "study_entity_id")}, - foreignKey = @ForeignKey(name = "studyEntity_importParameters_fk1")) + indexes = {@Index(name = "studyEntity_importParameters_idx1", columnList = "study_entity_id")}, + foreignKey = @ForeignKey(name = "studyEntity_importParameters_fk1")) private Map importParameters; @Enumerated(EnumType.STRING) @@ -132,5 +123,19 @@ public class StudyEntity extends AbstractManuallyAssignedIdentifierEntity public static class StudyNetworkUuid { UUID networkUuid; } + + //TODO temporary, for now we are only working with one rootNetwork + @Transient + public RootNetworkEntity getFirstRootNetwork() { + return rootNetworks.get(0); + } + + public void addRootNetwork(RootNetworkEntity rootNetworkEntity) { + if (rootNetworks == null) { + rootNetworks = new ArrayList<>(); + } + rootNetworkEntity.setStudy(this); + rootNetworks.add(rootNetworkEntity); + } } diff --git a/src/main/java/org/gridsuite/study/server/repository/networkmodificationtree/NetworkModificationNodeInfoRepository.java b/src/main/java/org/gridsuite/study/server/repository/networkmodificationtree/NetworkModificationNodeInfoRepository.java index 2d5967f28..0dcfef8c8 100644 --- a/src/main/java/org/gridsuite/study/server/repository/networkmodificationtree/NetworkModificationNodeInfoRepository.java +++ b/src/main/java/org/gridsuite/study/server/repository/networkmodificationtree/NetworkModificationNodeInfoRepository.java @@ -17,25 +17,5 @@ * @author Jacques Borsenberger { - List findAllByLoadFlowResultUuidNotNull(); - - List findAllByDynamicSimulationResultUuidNotNull(); - - List findAllBySecurityAnalysisResultUuidNotNull(); - - List findAllBySensitivityAnalysisResultUuidNotNull(); - - List findAllByNonEvacuatedEnergyResultUuidNotNull(); - - List findAllByShortCircuitAnalysisResultUuidNotNull(); - - List findAllByOneBusShortCircuitAnalysisResultUuidNotNull(); - - List findAllByVoltageInitResultUuidNotNull(); - - List findAllByNodeStudyId(UUID studyUuid); - List findAllByNodeStudyIdAndName(UUID studyUuid, String name); - - List findAllByStateEstimationResultUuidNotNull(); } diff --git a/src/main/java/org/gridsuite/study/server/repository/networkmodificationtree/NodeInfoRepository.java b/src/main/java/org/gridsuite/study/server/repository/networkmodificationtree/NodeInfoRepository.java index 22a0f695c..30c76bcd7 100644 --- a/src/main/java/org/gridsuite/study/server/repository/networkmodificationtree/NodeInfoRepository.java +++ b/src/main/java/org/gridsuite/study/server/repository/networkmodificationtree/NodeInfoRepository.java @@ -12,6 +12,7 @@ import org.springframework.data.repository.NoRepositoryBean; import java.util.Collection; +import java.util.List; import java.util.UUID; /** @@ -21,4 +22,5 @@ public interface NodeInfoRepository extends JpaRepository { void deleteByIdNodeIn(Collection ids); + List findAllByNodeStudyId(UUID studyId); } diff --git a/src/main/java/org/gridsuite/study/server/repository/rootnetwork/RootNetworkEntity.java b/src/main/java/org/gridsuite/study/server/repository/rootnetwork/RootNetworkEntity.java new file mode 100644 index 000000000..fd88916b1 --- /dev/null +++ b/src/main/java/org/gridsuite/study/server/repository/rootnetwork/RootNetworkEntity.java @@ -0,0 +1,68 @@ +/* + * 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.repository.rootnetwork; + +import jakarta.persistence.*; +import lombok.*; +import org.gridsuite.study.server.networkmodificationtree.entities.RootNetworkNodeInfoEntity; +import org.gridsuite.study.server.repository.StudyEntity; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * @author Le Saulnier Kevin + */ +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@Entity +@Builder +@Table(name = "rootNetwork", + indexes = {@Index(name = "rootNetworkEntity_studyId_idx", columnList = "study_uuid")}) +public class RootNetworkEntity { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id") + private UUID id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "studyUuid", foreignKey = @ForeignKey(name = "rootNetwork_study_id_fk_constraint")) + private StudyEntity study; + + @OneToMany(orphanRemoval = true, mappedBy = "rootNetwork", cascade = CascadeType.ALL) + private List rootNetworkNodeInfos; + + @Column(name = "networkUuid", nullable = false) + private UUID networkUuid; + + @Column(name = "networkId", nullable = false) + private String networkId; + + @Column(name = "caseFormat", nullable = false) + private String caseFormat; + + @Column(name = "caseUuid", nullable = false) + private UUID caseUuid; + + @Column(name = "caseName", nullable = false) + private String caseName; + + // reportUuid of network import, root node one + @Column(name = "reportUuid") + private UUID reportUuid; + + public void addRootNetworkNodeInfo(RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity) { + if (rootNetworkNodeInfos == null) { + rootNetworkNodeInfos = new ArrayList<>(); + } + rootNetworkNodeInfoEntity.setRootNetwork(this); + rootNetworkNodeInfos.add(rootNetworkNodeInfoEntity); + } +} diff --git a/src/main/java/org/gridsuite/study/server/repository/rootnetwork/RootNetworkNodeInfoRepository.java b/src/main/java/org/gridsuite/study/server/repository/rootnetwork/RootNetworkNodeInfoRepository.java new file mode 100644 index 000000000..89dd71c17 --- /dev/null +++ b/src/main/java/org/gridsuite/study/server/repository/rootnetwork/RootNetworkNodeInfoRepository.java @@ -0,0 +1,41 @@ +/* + * 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.repository.rootnetwork; + +import org.gridsuite.study.server.networkmodificationtree.entities.RootNetworkNodeInfoEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +/** + * @author Le Saulnier Kevin + */ +public interface RootNetworkNodeInfoRepository extends JpaRepository { + List findAllByLoadFlowResultUuidNotNull(); + + List findAllByDynamicSimulationResultUuidNotNull(); + + List findAllBySecurityAnalysisResultUuidNotNull(); + + List findAllBySensitivityAnalysisResultUuidNotNull(); + + List findAllByNonEvacuatedEnergyResultUuidNotNull(); + + List findAllByShortCircuitAnalysisResultUuidNotNull(); + + List findAllByOneBusShortCircuitAnalysisResultUuidNotNull(); + + List findAllByVoltageInitResultUuidNotNull(); + + List findAllByStateEstimationResultUuidNotNull(); + + List findAllByNodeInfoId(UUID nodeInfoId); + + Optional findByNodeInfoIdAndRootNetworkId(UUID nodeInfoId, UUID rootNetworkUuid); +} diff --git a/src/main/java/org/gridsuite/study/server/repository/rootnetwork/RootNetworkRepository.java b/src/main/java/org/gridsuite/study/server/repository/rootnetwork/RootNetworkRepository.java new file mode 100644 index 000000000..4850bf315 --- /dev/null +++ b/src/main/java/org/gridsuite/study/server/repository/rootnetwork/RootNetworkRepository.java @@ -0,0 +1,25 @@ +/* + * 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.repository.rootnetwork; + +import org.springframework.data.jpa.repository.EntityGraph; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.UUID; + +/** + * @author Le Saulnier Kevin + */ +@Repository +public interface RootNetworkRepository extends JpaRepository { + List findAllByStudyId(UUID studyUuid); + + @EntityGraph(attributePaths = {"rootNetworkNodeInfos"}, type = EntityGraph.EntityGraphType.LOAD) + List findAllWithInfosByStudyId(UUID studyUuid); +} diff --git a/src/main/java/org/gridsuite/study/server/service/ConsumerService.java b/src/main/java/org/gridsuite/study/server/service/ConsumerService.java index c366eddca..21d7618e9 100644 --- a/src/main/java/org/gridsuite/study/server/service/ConsumerService.java +++ b/src/main/java/org/gridsuite/study/server/service/ConsumerService.java @@ -106,7 +106,7 @@ public Consumer> consumeBuildResult() { LOGGER.info("Build completed for node '{}'", receiverObj.getNodeUuid()); - networkModificationTreeService.updateNodeBuildStatus(receiverObj.getNodeUuid(), + networkModificationTreeService.updateNodeBuildStatus(receiverObj.getNodeUuid(), receiverObj.getRootNetworkUuid(), NodeBuildStatus.from(networkModificationResult.getLastGroupApplicationStatus(), networkModificationResult.getApplicationStatus())); UUID studyUuid = networkModificationTreeService.getStudyUuidForNodeId(receiverObj.getNodeUuid()); @@ -130,7 +130,7 @@ public Consumer> consumeBuildStopped() { LOGGER.info("Build stopped for node '{}'", receiverObj.getNodeUuid()); - networkModificationTreeService.updateNodeBuildStatus(receiverObj.getNodeUuid(), NodeBuildStatus.from(BuildStatus.NOT_BUILT)); + networkModificationTreeService.updateNodeBuildStatus(receiverObj.getNodeUuid(), receiverObj.getRootNetworkUuid(), NodeBuildStatus.from(BuildStatus.NOT_BUILT)); // send notification UUID studyUuid = networkModificationTreeService.getStudyUuidForNodeId(receiverObj.getNodeUuid()); @@ -154,7 +154,7 @@ public Consumer> consumeBuildFailed() { LOGGER.info("Build failed for node '{}'", receiverObj.getNodeUuid()); - networkModificationTreeService.updateNodeBuildStatus(receiverObj.getNodeUuid(), NodeBuildStatus.from(BuildStatus.NOT_BUILT)); + networkModificationTreeService.updateNodeBuildStatus(receiverObj.getNodeUuid(), receiverObj.getRootNetworkUuid(), NodeBuildStatus.from(BuildStatus.NOT_BUILT)); // send notification UUID studyUuid = networkModificationTreeService.getStudyUuidForNodeId(receiverObj.getNodeUuid()); @@ -180,7 +180,6 @@ public Consumer> consumeCaseImportSucceeded() { if (rawParameters != null) { rawParameters.forEach((key, value) -> importParameters.put(key, value.toString())); } - NetworkInfos networkInfos = new NetworkInfos(networkUuid, networkId); if (receiverString != null) { CaseImportReceiver receiver; @@ -197,6 +196,8 @@ public Consumer> consumeCaseImportSucceeded() { Long startTime = receiver.getStartTime(); UUID importReportUuid = receiver.getReportUuid(); + CaseInfos caseInfos = new CaseInfos(caseUuid, caseName, caseFormat); + NetworkInfos networkInfos = new NetworkInfos(networkUuid, networkId); StudyEntity studyEntity = studyRepository.findById(studyUuid).orElse(null); try { if (studyEntity != null) { @@ -209,7 +210,7 @@ public Consumer> consumeCaseImportSucceeded() { UUID shortCircuitParametersUuid = createDefaultShortCircuitAnalysisParameters(); UUID securityAnalysisParametersUuid = createDefaultSecurityAnalysisParameters(); UUID sensitivityAnalysisParametersUuid = createDefaultSensitivityAnalysisParameters(); - studyService.insertStudy(studyUuid, userId, networkInfos, caseFormat, caseUuid, caseName, loadFlowParametersUuid, shortCircuitParametersUuid, DynamicSimulationService.toEntity(dynamicSimulationParameters, objectMapper), null, securityAnalysisParametersUuid, sensitivityAnalysisParametersUuid, importParameters, importReportUuid); + studyService.insertStudy(studyUuid, userId, networkInfos, caseInfos, loadFlowParametersUuid, shortCircuitParametersUuid, DynamicSimulationService.toEntity(dynamicSimulationParameters, objectMapper), null, securityAnalysisParametersUuid, sensitivityAnalysisParametersUuid, importParameters, importReportUuid); } caseService.disableCaseExpiration(caseUuid); } catch (Exception e) { @@ -329,7 +330,7 @@ public void consumeCalculationFailed(Message msg, ComputationType comput // delete computation results from the databases // ==> will probably be removed soon because it prevents the front from recovering the resultId ; or 'null' parameter will be replaced by null like in VOLTAGE_INITIALIZATION - networkModificationTreeService.updateComputationResultUuid(receiverObj.getNodeUuid(), resultUuid, computationType); + networkModificationTreeService.updateComputationResultUuid(receiverObj.getNodeUuid(), receiverObj.getRootNetworkUuid(), resultUuid, computationType); UUID studyUuid = networkModificationTreeService.getStudyUuidForNodeId(receiverObj.getNodeUuid()); // send notification for failed computation @@ -353,7 +354,7 @@ public void consumeCalculationStopped(Message msg, ComputationType compu receiverObj = objectMapper.readValue(URLDecoder.decode(receiver, StandardCharsets.UTF_8), NodeReceiver.class); // delete computation results from the database - networkModificationTreeService.updateComputationResultUuid(receiverObj.getNodeUuid(), null, computationType); + networkModificationTreeService.updateComputationResultUuid(receiverObj.getNodeUuid(), receiverObj.getRootNetworkUuid(), null, computationType); UUID studyUuid = networkModificationTreeService.getStudyUuidForNodeId(receiverObj.getNodeUuid()); // send notification for stopped computation notificationService.emitStudyChanged(studyUuid, receiverObj.getNodeUuid(), computationType.getUpdateStatusType()); @@ -399,7 +400,7 @@ public void consumeCalculationResult(Message msg, ComputationType comput receiverObj.getNodeUuid()); // update DB - networkModificationTreeService.updateComputationResultUuid(receiverObj.getNodeUuid(), resultUuid, computationType); + networkModificationTreeService.updateComputationResultUuid(receiverObj.getNodeUuid(), receiverObj.getRootNetworkUuid(), resultUuid, computationType); UUID studyUuid = networkModificationTreeService.getStudyUuidForNodeId(receiverObj.getNodeUuid()); // send notifications diff --git a/src/main/java/org/gridsuite/study/server/service/LoadFlowService.java b/src/main/java/org/gridsuite/study/server/service/LoadFlowService.java index d3c83af75..a0d668138 100644 --- a/src/main/java/org/gridsuite/study/server/service/LoadFlowService.java +++ b/src/main/java/org/gridsuite/study/server/service/LoadFlowService.java @@ -60,13 +60,13 @@ public LoadFlowService(RemoteServicesProperties remoteServicesProperties, this.restTemplate = restTemplate; } - public UUID runLoadFlow(UUID studyUuid, UUID nodeUuid, UUID parametersUuid, UUID reportUuid, String userId, Float limitReduction) { + public UUID runLoadFlow(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, UUID parametersUuid, UUID reportUuid, String userId, Float limitReduction) { UUID networkUuid = networkStoreService.getNetworkUuid(studyUuid); - String variantId = getVariantId(nodeUuid); + String variantId = getVariantId(nodeUuid, rootNetworkUuid); String receiver; try { - receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid)), StandardCharsets.UTF_8); + receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid, rootNetworkUuid)), StandardCharsets.UTF_8); } catch (JsonProcessingException e) { throw new UncheckedIOException(e); } @@ -120,11 +120,11 @@ public Integer getLoadFlowResultsCount() { return restTemplate.getForObject(loadFlowServerBaseUri + path, Integer.class); } - public String getLoadFlowResultOrStatus(UUID nodeUuid, String filters, Sort sort, String suffix) { + public String getLoadFlowResultOrStatus(UUID nodeUuid, UUID rootNetworkUuid, String filters, Sort sort, String suffix) { String result; - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.LOAD_FLOW); + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.LOAD_FLOW); - if (resultUuidOpt.isEmpty()) { + if (resultUuid == null) { return null; } @@ -135,7 +135,7 @@ public String getLoadFlowResultOrStatus(UUID nodeUuid, String filters, Sort sort if (sort != null) { sort.forEach(order -> uriComponentsBuilder.queryParam("sort", order.getProperty() + "," + order.getDirection())); } - String path = uriComponentsBuilder.buildAndExpand(resultUuidOpt.get()).toUriString(); + String path = uriComponentsBuilder.buildAndExpand(resultUuid).toUriString(); try { result = restTemplate.getForObject(loadFlowServerBaseUri + path, String.class); @@ -148,33 +148,33 @@ public String getLoadFlowResultOrStatus(UUID nodeUuid, String filters, Sort sort return result; } - public String getLoadFlowResult(UUID nodeUuid, String filters, Sort sort) { - return getLoadFlowResultOrStatus(nodeUuid, filters, sort, ""); + public String getLoadFlowResult(UUID nodeUuid, UUID rootNetworkUuid, String filters, Sort sort) { + return getLoadFlowResultOrStatus(nodeUuid, rootNetworkUuid, filters, sort, ""); } - public String getLoadFlowStatus(UUID nodeUuid) { - return getLoadFlowResultOrStatus(nodeUuid, null, null, "/status"); + public String getLoadFlowStatus(UUID nodeUuid, UUID rootNetworkUuid) { + return getLoadFlowResultOrStatus(nodeUuid, rootNetworkUuid, null, null, "/status"); } - public void stopLoadFlow(UUID studyUuid, UUID nodeUuid, String userId) { + public void stopLoadFlow(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, String userId) { Objects.requireNonNull(studyUuid); Objects.requireNonNull(nodeUuid); Objects.requireNonNull(userId); - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.LOAD_FLOW); - if (resultUuidOpt.isEmpty()) { + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.LOAD_FLOW); + if (resultUuid == null) { return; } String receiver; try { - receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid)), StandardCharsets.UTF_8); + receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid, rootNetworkUuid)), StandardCharsets.UTF_8); } catch (JsonProcessingException e) { throw new UncheckedIOException(e); } String path = UriComponentsBuilder .fromPath(DELIMITER + LOADFLOW_API_VERSION + "/results/{resultUuid}/stop") - .queryParam(QUERY_PARAM_RECEIVER, receiver).buildAndExpand(resultUuidOpt.get()).toUriString(); + .queryParam(QUERY_PARAM_RECEIVER, receiver).buildAndExpand(resultUuid).toUriString(); HttpHeaders headers = new HttpHeaders(); headers.set(HEADER_USER_ID, userId); @@ -193,26 +193,26 @@ public void invalidateLoadFlowStatus(List uuids) { } } - private String getVariantId(UUID nodeUuid) { - return networkModificationTreeService.getVariantId(nodeUuid); + private String getVariantId(UUID nodeUuid, UUID rootNetworkUuid) { + return networkModificationTreeService.getVariantId(nodeUuid, rootNetworkUuid); } public void setLoadFlowServerBaseUri(String loadFlowServerBaseUri) { this.loadFlowServerBaseUri = loadFlowServerBaseUri; } - public void assertLoadFlowNotRunning(UUID nodeUuid) { - String scs = getLoadFlowStatus(nodeUuid); + public void assertLoadFlowNotRunning(UUID nodeUuid, UUID rootNetworkUuid) { + String scs = getLoadFlowStatus(nodeUuid, rootNetworkUuid); if (LoadFlowStatus.RUNNING.name().equals(scs)) { throw new StudyException(LOADFLOW_RUNNING); } } - public List getLimitViolations(UUID nodeUuid, String filters, String globalFilters, Sort sort, UUID networkUuid, String variantId) { + public List getLimitViolations(UUID nodeUuid, UUID rootNetworkUuid, String filters, String globalFilters, Sort sort, UUID networkUuid, String variantId) { List result = new ArrayList<>(); - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.LOAD_FLOW); + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.LOAD_FLOW); - if (resultUuidOpt.isPresent()) { + if (resultUuid != null) { UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath(DELIMITER + LOADFLOW_API_VERSION + "/results/{resultUuid}/limit-violations"); if (!StringUtils.isEmpty(filters)) { uriComponentsBuilder.queryParam("filters", URLEncoder.encode(filters, StandardCharsets.UTF_8)); @@ -227,7 +227,7 @@ public List getLimitViolations(UUID nodeUuid, String filter if (sort != null) { sort.forEach(order -> uriComponentsBuilder.queryParam("sort", order.getProperty() + "," + order.getDirection())); } - String path = uriComponentsBuilder.buildAndExpand(resultUuidOpt.get()).toUriString(); + String path = uriComponentsBuilder.buildAndExpand(resultUuid).toUriString(); try { ResponseEntity> responseEntity = restTemplate.exchange(loadFlowServerBaseUri + path, HttpMethod.GET, null, new ParameterizedTypeReference<>() { }); diff --git a/src/main/java/org/gridsuite/study/server/service/NetworkModificationService.java b/src/main/java/org/gridsuite/study/server/service/NetworkModificationService.java index aadf78f53..873e3c2ef 100644 --- a/src/main/java/org/gridsuite/study/server/service/NetworkModificationService.java +++ b/src/main/java/org/gridsuite/study/server/service/NetworkModificationService.java @@ -12,9 +12,10 @@ import org.apache.commons.lang3.StringUtils; import org.gridsuite.study.server.RemoteServicesProperties; import org.gridsuite.study.server.dto.BuildInfos; -import org.gridsuite.study.server.dto.NodeModificationInfos; import org.gridsuite.study.server.dto.NodeReceiver; import org.gridsuite.study.server.dto.modification.NetworkModificationResult; +import org.gridsuite.study.server.networkmodificationtree.entities.NetworkModificationNodeInfoEntity; +import org.gridsuite.study.server.networkmodificationtree.entities.RootNetworkNodeInfoEntity; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpEntity; @@ -272,9 +273,9 @@ public void restoreModifications(UUID groupUUid, List modificationsUuids) } } - void buildNode(@NonNull UUID studyUuid, @NonNull UUID nodeUuid, @NonNull BuildInfos buildInfos) { + void buildNode(@NonNull UUID studyUuid, @NonNull UUID nodeUuid, @NonNull UUID rootNetworkUuid, @NonNull BuildInfos buildInfos) { UUID networkUuid = networkStoreService.getNetworkUuid(studyUuid); - String receiver = buildReceiver(nodeUuid); + String receiver = buildReceiver(nodeUuid, rootNetworkUuid); var uriComponentsBuilder = UriComponentsBuilder.fromPath(buildPathFrom(networkUuid) + "build"); var path = uriComponentsBuilder @@ -290,8 +291,8 @@ void buildNode(@NonNull UUID studyUuid, @NonNull UUID nodeUuid, @NonNull BuildIn restTemplate.exchange(getNetworkModificationServerURI(true) + path, HttpMethod.POST, httpEntity, Void.class); } - public void stopBuild(@NonNull UUID nodeUuid) { - String receiver = buildReceiver(nodeUuid); + public void stopBuild(@NonNull UUID nodeUuid, @NonNull UUID rootNetworkUuid) { + String receiver = buildReceiver(nodeUuid, rootNetworkUuid); var path = UriComponentsBuilder.fromPath("build/stop") .queryParam(QUERY_PARAM_RECEIVER, receiver) .build() @@ -312,14 +313,14 @@ private HttpEntity getModificationsUuidBody(List modificationUuidL return httpEntity; } - public Optional moveModifications(UUID originGroupUuid, List modificationUuidList, UUID beforeUuid, UUID networkUuid, NodeModificationInfos nodeInfos, boolean buildTargetNode) { + public Optional moveModifications(UUID originGroupUuid, List modificationUuidList, UUID beforeUuid, UUID networkUuid, NetworkModificationNodeInfoEntity networkModificationNodeInfoEntity, RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity, boolean buildTargetNode) { Objects.requireNonNull(networkUuid); var path = UriComponentsBuilder.fromPath(GROUP_PATH) .queryParam(QUERY_PARAM_ACTION, ModificationsActionType.MOVE.name()) .queryParam(NETWORK_UUID, networkUuid) - .queryParam(REPORT_UUID, nodeInfos.getReportUuid()) - .queryParam(REPORTER_ID, nodeInfos.getId()) - .queryParam(VARIANT_ID, nodeInfos.getVariantId()) + .queryParam(REPORT_UUID, rootNetworkNodeInfoEntity.getModificationReports().get(networkModificationNodeInfoEntity.getId())) + .queryParam(REPORTER_ID, networkModificationNodeInfoEntity.getId()) + .queryParam(VARIANT_ID, rootNetworkNodeInfoEntity.getVariantId()) .queryParam("originGroupUuid", originGroupUuid) .queryParam("build", buildTargetNode); if (beforeUuid != null) { @@ -329,24 +330,24 @@ public Optional moveModifications(UUID originGroupUui HttpEntity httpEntity = getModificationsUuidBody(modificationUuidList); return restTemplate.exchange( - getNetworkModificationServerURI(false) + path.buildAndExpand(nodeInfos.getModificationGroupUuid()).toUriString(), + getNetworkModificationServerURI(false) + path.buildAndExpand(networkModificationNodeInfoEntity.getModificationGroupUuid()).toUriString(), HttpMethod.PUT, httpEntity, new ParameterizedTypeReference>() { }).getBody(); } - public Optional createModifications(List modificationUuidList, UUID networkUuid, NodeModificationInfos nodeInfos, ModificationsActionType action) { + public Optional createModifications(List modificationUuidList, UUID networkUuid, NetworkModificationNodeInfoEntity networkModificationNodeInfoEntity, RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity, ModificationsActionType action) { var path = UriComponentsBuilder.fromPath(GROUP_PATH) .queryParam(QUERY_PARAM_ACTION, action.name()) .queryParam(NETWORK_UUID, networkUuid) - .queryParam(REPORT_UUID, nodeInfos.getReportUuid()) - .queryParam(REPORTER_ID, nodeInfos.getId()) - .queryParam(VARIANT_ID, nodeInfos.getVariantId()); + .queryParam(REPORT_UUID, rootNetworkNodeInfoEntity.getModificationReports().get(networkModificationNodeInfoEntity.getId())) + .queryParam(REPORTER_ID, networkModificationNodeInfoEntity.getId()) + .queryParam(VARIANT_ID, rootNetworkNodeInfoEntity.getVariantId()); HttpEntity httpEntity = getModificationsUuidBody(modificationUuidList); return restTemplate.exchange( - getNetworkModificationServerURI(false) + path.buildAndExpand(nodeInfos.getModificationGroupUuid()).toUriString(), + getNetworkModificationServerURI(false) + path.buildAndExpand(networkModificationNodeInfoEntity.getModificationGroupUuid()).toUriString(), HttpMethod.PUT, httpEntity, new ParameterizedTypeReference>() { @@ -372,29 +373,29 @@ public void createModifications(UUID sourceGroupUuid, UUID groupUuid) { } } - public Optional duplicateModificationsInGroup(UUID originGroupUuid, UUID networkUuid, NodeModificationInfos nodeInfos) { + public Optional duplicateModificationsInGroup(UUID originGroupUuid, UUID networkUuid, NetworkModificationNodeInfoEntity networkModificationNodeInfoEntity, RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity) { var path = UriComponentsBuilder.fromPath(GROUP_PATH + DELIMITER + "duplications") .queryParam(NETWORK_UUID, networkUuid) - .queryParam(REPORT_UUID, nodeInfos.getReportUuid()) - .queryParam(REPORTER_ID, nodeInfos.getId()) - .queryParam(VARIANT_ID, nodeInfos.getVariantId()) + .queryParam(REPORT_UUID, rootNetworkNodeInfoEntity.getModificationReports().get(networkModificationNodeInfoEntity.getId())) + .queryParam(REPORTER_ID, networkModificationNodeInfoEntity.getId()) + .queryParam(VARIANT_ID, rootNetworkNodeInfoEntity.getVariantId()) .queryParam("duplicateFrom", originGroupUuid); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); return restTemplate.exchange( - getNetworkModificationServerURI(false) + path.buildAndExpand(nodeInfos.getModificationGroupUuid()).toUriString(), + getNetworkModificationServerURI(false) + path.buildAndExpand(networkModificationNodeInfoEntity.getModificationGroupUuid()).toUriString(), HttpMethod.PUT, new HttpEntity<>(headers), new ParameterizedTypeReference>() { }).getBody(); } - private String buildReceiver(UUID nodeUuid) { + private String buildReceiver(UUID nodeUuid, UUID rootNetworkUuid) { String receiver; try { - receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid)), + receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid, rootNetworkUuid)), StandardCharsets.UTF_8); } catch (JsonProcessingException e) { throw new UncheckedIOException(e); diff --git a/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java b/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java index bf1a0d99b..3d37983de 100644 --- a/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java +++ b/src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java @@ -6,6 +6,7 @@ */ package org.gridsuite.study.server.service; +import jakarta.persistence.EntityNotFoundException; import lombok.NonNull; import org.apache.commons.lang3.StringUtils; import org.gridsuite.study.server.StudyException; @@ -20,27 +21,21 @@ import org.gridsuite.study.server.repository.networkmodificationtree.NetworkModificationNodeInfoRepository; import org.gridsuite.study.server.repository.networkmodificationtree.NodeRepository; import org.gridsuite.study.server.repository.networkmodificationtree.RootNodeInfoRepository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkEntity; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkNodeInfoRepository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkRepository; import org.springframework.context.annotation.Lazy; import org.springframework.data.util.Pair; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import jakarta.persistence.EntityNotFoundException; - import java.time.Instant; import java.util.*; +import java.util.function.Function; import java.util.stream.Collectors; import static org.gridsuite.study.server.StudyException.Type.*; -import static org.gridsuite.study.server.dto.ComputationType.DYNAMIC_SIMULATION; -import static org.gridsuite.study.server.dto.ComputationType.LOAD_FLOW; -import static org.gridsuite.study.server.dto.ComputationType.NON_EVACUATED_ENERGY_ANALYSIS; -import static org.gridsuite.study.server.dto.ComputationType.SECURITY_ANALYSIS; -import static org.gridsuite.study.server.dto.ComputationType.SENSITIVITY_ANALYSIS; -import static org.gridsuite.study.server.dto.ComputationType.SHORT_CIRCUIT; -import static org.gridsuite.study.server.dto.ComputationType.SHORT_CIRCUIT_ONE_BUS; -import static org.gridsuite.study.server.dto.ComputationType.VOLTAGE_INITIALIZATION; -import static org.gridsuite.study.server.dto.ComputationType.STATE_ESTIMATION; +import static org.gridsuite.study.server.dto.ComputationType.*; /** * @author Jacques Borsenberger - public AbstractNode createNode(UUID studyUuid, UUID nodeId, AbstractNode nodeInfo, InsertMode insertMode, String userId) { + private NetworkModificationNode createAndInsertNode(StudyEntity study, UUID nodeId, NetworkModificationNode nodeInfo, InsertMode insertMode, String userId) { Optional referenceNode = nodesRepository.findById(nodeId); return referenceNode.map(reference -> { - assertNodeNameNotExist(studyUuid, nodeInfo.getName()); + assertNodeNameNotExist(study.getId(), nodeInfo.getName()); if (insertMode.equals(InsertMode.BEFORE) && reference.getType().equals(NodeType.ROOT)) { throw new StudyException(NOT_ALLOWED); } NodeEntity parent = insertMode.equals(InsertMode.BEFORE) ? reference.getParentNode() : reference; - NodeEntity node = nodesRepository.save(new NodeEntity(null, parent, nodeInfo.getType(), reference.getStudy(), false, null)); + NodeEntity node = createNetworkModificationNode(study, parent, nodeInfo); nodeInfo.setId(node.getIdNode()); - repositories.get(node.getType()).createNodeInfo(nodeInfo); if (insertMode.equals(InsertMode.BEFORE)) { reference.setParentNode(node); } else if (insertMode.equals(InsertMode.AFTER)) { nodesRepository.findAllByParentNodeIdNode(nodeId).stream() - .filter(n -> !n.getIdNode().equals(node.getIdNode())) - .forEach(child -> child.setParentNode(node)); + .filter(n -> !n.getIdNode().equals(node.getIdNode())) + .forEach(child -> child.setParentNode(node)); } - notificationService.emitNodeInserted(self.getStudyUuidForNodeId(nodeId), parent.getIdNode(), node.getIdNode(), insertMode, nodeId); + notificationService.emitNodeInserted(study.getId(), parent.getIdNode(), node.getIdNode(), insertMode, nodeId); // userId is null when creating initial nodes, we don't need to send element update notifications in this case if (userId != null) { - notificationService.emitElementUpdated(studyUuid, userId); + notificationService.emitElementUpdated(study.getId(), userId); } return nodeInfo; }).orElseThrow(() -> new StudyException(ELEMENT_NOT_FOUND)); } + @Transactional + public NetworkModificationNode createNode(@NonNull StudyEntity study, @NonNull UUID nodeId, @NonNull NetworkModificationNode nodeInfo, @NonNull InsertMode insertMode, String userId) { + // create new node + NetworkModificationNode newNode = createAndInsertNode(study, nodeId, nodeInfo, insertMode, userId); + + NetworkModificationNodeInfoEntity newNodeInfoEntity = networkModificationNodeInfoRepository.getReferenceById(newNode.getId()); + rootNetworkNodeInfoService.createNodeLinks(Objects.requireNonNull(study.getId()), newNodeInfoEntity, nodeInfo); + + return newNode; + } + @Transactional public UUID duplicateStudyNode(UUID nodeToCopyUuid, UUID anchorNodeUuid, InsertMode insertMode) { NodeEntity anchorNode = nodesRepository.findById(anchorNodeUuid).orElseThrow(() -> new StudyException(ELEMENT_NOT_FOUND)); @@ -135,7 +169,7 @@ private UUID duplicateNode(UUID nodeToCopyUuid, UUID anchorNodeUuid, InsertMode networkModificationService.createModifications(modificationGroupUuid, newGroupUuid); NodeEntity parent = insertMode.equals(InsertMode.BEFORE) ? - anchorNodeEntity.getParentNode() : anchorNodeEntity; + anchorNodeEntity.getParentNode() : anchorNodeEntity; //Then we create the node NodeEntity node = nodesRepository.save(new NodeEntity(null, parent, nodeToCopyEntity.getType(), anchorNodeEntity.getStudy(), false, null)); @@ -143,34 +177,26 @@ private UUID duplicateNode(UUID nodeToCopyUuid, UUID anchorNodeUuid, InsertMode anchorNodeEntity.setParentNode(node); } else if (insertMode.equals(InsertMode.AFTER)) { nodesRepository.findAllByParentNodeIdNode(anchorNodeUuid).stream() - .filter(n -> !n.getIdNode().equals(node.getIdNode())) - .forEach(child -> child.setParentNode(node)); + .filter(n -> !n.getIdNode().equals(node.getIdNode())) + .forEach(child -> child.setParentNode(node)); } //And the modification node info NetworkModificationNodeInfoEntity networkModificationNodeInfoEntity = networkModificationNodeInfoRepository.findById(nodeToCopyUuid).orElseThrow(() -> new StudyException(GET_MODIFICATIONS_FAILED)); - NetworkModificationNodeInfoEntity newNetworkModificationNodeInfoEntity = new NetworkModificationNodeInfoEntity( - newGroupUuid, - UUID.randomUUID().toString(), - null, - null, - null, - null, - null, - null, - null, - null, - null, - NodeBuildStatus.from(BuildStatus.NOT_BUILT).toEntity(), - new HashMap<>(), - new HashMap<>() - ); UUID studyUuid = anchorNodeEntity.getStudy().getId(); - newNetworkModificationNodeInfoEntity.setName(getSuffixedNodeName(studyUuid, networkModificationNodeInfoEntity.getName())); - newNetworkModificationNodeInfoEntity.setDescription(networkModificationNodeInfoEntity.getDescription()); - newNetworkModificationNodeInfoEntity.setIdNode(node.getIdNode()); - newNetworkModificationNodeInfoEntity.setModificationReports(new HashMap<>(Map.of(node.getIdNode(), newReportUuid))); - networkModificationNodeInfoRepository.save(newNetworkModificationNodeInfoEntity); + NetworkModificationNodeInfoEntity newNetworkModificationNodeInfoEntity = networkModificationNodeInfoRepository.save( + NetworkModificationNodeInfoEntity.builder() + .modificationGroupUuid(newGroupUuid) + .name(getSuffixedNodeName(studyUuid, networkModificationNodeInfoEntity.getName())) + .description(networkModificationNodeInfoEntity.getDescription()) + .idNode(node.getIdNode()) + .build() + ); + + NetworkModificationNode modificationNode = NetworkModificationNode.builder() + .modificationReports(new HashMap<>(Map.of(node.getIdNode(), newReportUuid))) + .build(); + rootNetworkNodeInfoService.createNodeLinks(Objects.requireNonNull(studyUuid), newNetworkModificationNodeInfoEntity, modificationNode); return node.getIdNode(); } @@ -217,7 +243,7 @@ private UUID moveNode(UUID nodeToMoveUuid, UUID anchorNodeUuid, InsertMode inser NodeEntity nodeToMoveEntity = nodeToMoveOpt.orElseThrow(() -> new StudyException(NODE_NOT_FOUND)); nodesRepository.findAllByParentNodeIdNode(nodeToMoveUuid) - .forEach(child -> child.setParentNode(nodeToMoveEntity.getParentNode())); + .forEach(child -> child.setParentNode(nodeToMoveEntity.getParentNode())); Optional anchorNodeOpt = nodesRepository.findById(anchorNodeUuid); NodeEntity anchorNodeEntity = anchorNodeOpt.orElseThrow(() -> new StudyException(NODE_NOT_FOUND)); @@ -227,14 +253,14 @@ private UUID moveNode(UUID nodeToMoveUuid, UUID anchorNodeUuid, InsertMode inser } NodeEntity parent = insertMode.equals(InsertMode.BEFORE) ? - anchorNodeEntity.getParentNode() : anchorNodeEntity; + anchorNodeEntity.getParentNode() : anchorNodeEntity; if (insertMode.equals(InsertMode.BEFORE)) { anchorNodeEntity.setParentNode(nodeToMoveEntity); } else if (insertMode.equals(InsertMode.AFTER)) { nodesRepository.findAllByParentNodeIdNode(anchorNodeUuid).stream() - .filter(n -> !n.getIdNode().equals(nodeToMoveEntity.getIdNode())) - .forEach(child -> child.setParentNode(nodeToMoveEntity)); + .filter(n -> !n.getIdNode().equals(nodeToMoveEntity.getIdNode())) + .forEach(child -> child.setParentNode(nodeToMoveEntity)); } nodeToMoveEntity.setParentNode(parent); @@ -282,7 +308,7 @@ private void stashNodes(UUID id, boolean stashChildren, List stashedNodes, nodesRepository.findAllByParentNodeIdNode(id).forEach(node -> node.setParentNode(nodeToStash.getParentNode())); } else { nodesRepository.findAllByParentNodeIdNode(id) - .forEach(child -> stashNodes(child.getIdNode(), true, stashedNodes, false)); + .forEach(child -> stashNodes(child.getIdNode(), true, stashedNodes, false)); } stashedNodes.add(id); nodeToStash.setStashed(true); @@ -302,70 +328,71 @@ private void deleteNodes(UUID id, boolean deleteChildren, boolean allowDeleteRoo throw new StudyException(CANT_DELETE_ROOT_NODE); } - UUID modificationGroupUuid = repositories.get(nodeToDelete.getType()).getModificationGroupUuid(id); + UUID modificationGroupUuid = self.getModificationGroupUuid(id); deleteNodeInfos.addModificationGroupUuid(modificationGroupUuid); - // delete all modification reports - repositories.get(nodeToDelete.getType()).getModificationReports(nodeToDelete.getIdNode()).forEach((key, value) -> deleteNodeInfos.addReportUuid(value)); - - // delete all computation reports - repositories.get(nodeToDelete.getType()).getComputationReports(nodeToDelete.getIdNode()).forEach((key, value) -> deleteNodeInfos.addReportUuid(value)); - - String variantId = repositories.get(nodeToDelete.getType()).getVariantId(id); - if (!StringUtils.isBlank(variantId)) { - deleteNodeInfos.addVariantId(variantId); - } - - UUID loadFlowResultUuid = repositories.get(nodeToDelete.getType()).getComputationResultUuid(id, LOAD_FLOW); - if (loadFlowResultUuid != null) { - deleteNodeInfos.addLoadFlowResultUuid(loadFlowResultUuid); - } - - UUID securityAnalysisResultUuid = repositories.get(nodeToDelete.getType()).getComputationResultUuid(id, SECURITY_ANALYSIS); - if (securityAnalysisResultUuid != null) { - deleteNodeInfos.addSecurityAnalysisResultUuid(securityAnalysisResultUuid); - } - - UUID sensitivityAnalysisResultUuid = repositories.get(nodeToDelete.getType()).getComputationResultUuid(id, SENSITIVITY_ANALYSIS); - if (sensitivityAnalysisResultUuid != null) { - deleteNodeInfos.addSensitivityAnalysisResultUuid(sensitivityAnalysisResultUuid); - } - - UUID nonEvacuatedEnergyResultUuid = repositories.get(nodeToDelete.getType()).getComputationResultUuid(id, NON_EVACUATED_ENERGY_ANALYSIS); - if (nonEvacuatedEnergyResultUuid != null) { - deleteNodeInfos.addNonEvacuatedEnergyResultUuid(nonEvacuatedEnergyResultUuid); - } - - UUID shortCircuitAnalysisResultUuid = repositories.get(nodeToDelete.getType()).getComputationResultUuid(id, SHORT_CIRCUIT); - if (shortCircuitAnalysisResultUuid != null) { - deleteNodeInfos.addShortCircuitAnalysisResultUuid(shortCircuitAnalysisResultUuid); - } - - UUID oneBusShortCircuitAnalysisResultUuid = repositories.get(nodeToDelete.getType()).getComputationResultUuid(id, SHORT_CIRCUIT_ONE_BUS); - if (oneBusShortCircuitAnalysisResultUuid != null) { - deleteNodeInfos.addOneBusShortCircuitAnalysisResultUuid(oneBusShortCircuitAnalysisResultUuid); - } - - UUID voltageInitResultUuid = repositories.get(nodeToDelete.getType()).getComputationResultUuid(id, VOLTAGE_INITIALIZATION); - if (voltageInitResultUuid != null) { - deleteNodeInfos.addVoltageInitResultUuid(voltageInitResultUuid); - } - - UUID dynamicSimulationResultUuid = repositories.get(nodeToDelete.getType()).getComputationResultUuid(id, DYNAMIC_SIMULATION); - if (dynamicSimulationResultUuid != null) { - deleteNodeInfos.addDynamicSimulationResultUuid(dynamicSimulationResultUuid); - } - - UUID stateEstimationResultUuid = repositories.get(nodeToDelete.getType()).getComputationResultUuid(id, STATE_ESTIMATION); - if (stateEstimationResultUuid != null) { - deleteNodeInfos.addStateEstimationResultUuid(stateEstimationResultUuid); - } + //get all rootnetworknodeinfo info linked to node + List rootNetworkNodeInfoEntity = rootNetworkNodeInfoRepository.findAllByNodeInfoId(id); + rootNetworkNodeInfoEntity.forEach(tpNodeinfo -> { + tpNodeinfo.getModificationReports().forEach((key, value) -> deleteNodeInfos.addReportUuid(value)); + tpNodeinfo.getComputationReports().forEach((key, value) -> deleteNodeInfos.addReportUuid(value)); + + String variantId = tpNodeinfo.getVariantId(); + if (!StringUtils.isBlank(variantId)) { + deleteNodeInfos.addVariantId(variantId); + } + + UUID loadFlowResultUuid = getComputationResultUuid(tpNodeinfo, LOAD_FLOW); + if (loadFlowResultUuid != null) { + deleteNodeInfos.addLoadFlowResultUuid(loadFlowResultUuid); + } + + UUID securityAnalysisResultUuid = getComputationResultUuid(tpNodeinfo, SECURITY_ANALYSIS); + if (securityAnalysisResultUuid != null) { + deleteNodeInfos.addSecurityAnalysisResultUuid(securityAnalysisResultUuid); + } + + UUID sensitivityAnalysisResultUuid = getComputationResultUuid(tpNodeinfo, SENSITIVITY_ANALYSIS); + if (sensitivityAnalysisResultUuid != null) { + deleteNodeInfos.addSensitivityAnalysisResultUuid(sensitivityAnalysisResultUuid); + } + + UUID nonEvacuatedEnergyResultUuid = getComputationResultUuid(tpNodeinfo, NON_EVACUATED_ENERGY_ANALYSIS); + if (nonEvacuatedEnergyResultUuid != null) { + deleteNodeInfos.addNonEvacuatedEnergyResultUuid(nonEvacuatedEnergyResultUuid); + } + + UUID shortCircuitAnalysisResultUuid = getComputationResultUuid(tpNodeinfo, SHORT_CIRCUIT); + if (shortCircuitAnalysisResultUuid != null) { + deleteNodeInfos.addShortCircuitAnalysisResultUuid(shortCircuitAnalysisResultUuid); + } + + UUID oneBusShortCircuitAnalysisResultUuid = getComputationResultUuid(tpNodeinfo, SHORT_CIRCUIT_ONE_BUS); + if (oneBusShortCircuitAnalysisResultUuid != null) { + deleteNodeInfos.addOneBusShortCircuitAnalysisResultUuid(oneBusShortCircuitAnalysisResultUuid); + } + + UUID voltageInitResultUuid = getComputationResultUuid(tpNodeinfo, VOLTAGE_INITIALIZATION); + if (voltageInitResultUuid != null) { + deleteNodeInfos.addVoltageInitResultUuid(voltageInitResultUuid); + } + + UUID dynamicSimulationResultUuid = getComputationResultUuid(tpNodeinfo, DYNAMIC_SIMULATION); + if (dynamicSimulationResultUuid != null) { + deleteNodeInfos.addDynamicSimulationResultUuid(dynamicSimulationResultUuid); + } + + UUID stateEstimationResultUuid = getComputationResultUuid(tpNodeinfo, STATE_ESTIMATION); + if (stateEstimationResultUuid != null) { + deleteNodeInfos.addStateEstimationResultUuid(stateEstimationResultUuid); + } + }); if (!deleteChildren) { nodesRepository.findAllByParentNodeIdNode(id).forEach(node -> node.setParentNode(nodeToDelete.getParentNode())); } else { nodesRepository.findAllByParentNodeIdNode(id) - .forEach(child -> deleteNodes(child.getIdNode(), true, false, removedNodes, deleteNodeInfos)); + .forEach(child -> deleteNodes(child.getIdNode(), true, false, removedNodes, deleteNodeInfos)); } removedNodes.add(id); repositories.get(nodeToDelete.getType()).deleteByNodeId(id); @@ -382,8 +409,8 @@ public void doDeleteTree(UUID studyId) { try { List nodes = nodesRepository.findAllByStudyId(studyId); repositories.forEach((key, repository) -> - repository.deleteAll( - nodes.stream().filter(n -> n.getType().equals(key)).map(NodeEntity::getIdNode).collect(Collectors.toSet())) + repository.deleteAll( + nodes.stream().filter(n -> n.getType().equals(key)).map(NodeEntity::getIdNode).collect(Collectors.toSet())) ); nodesRepository.deleteAll(nodes); } catch (EntityNotFoundException ignored) { @@ -392,16 +419,16 @@ public void doDeleteTree(UUID studyId) { } @Transactional - public NodeEntity createRoot(StudyEntity study, UUID importReportUuid) { + public NodeEntity createRoot(StudyEntity study) { NodeEntity node = nodesRepository.save(new NodeEntity(null, null, NodeType.ROOT, study, false, null)); - var root = RootNode.builder() - .studyId(study.getId()) - .id(node.getIdNode()) + rootNodeInfoRepository.save( + RootNodeInfoEntity.builder() + .idNode(node.getIdNode()) .name(ROOT_NODE_NAME) .readOnly(true) - .reportUuid(importReportUuid) - .build(); - repositories.get(node.getType()).createNodeInfo(root); + .build() + ); + return node; } @@ -411,13 +438,16 @@ public RootNode getStudyTree(UUID studyId) { if (nodes.isEmpty()) { throw new StudyException(ELEMENT_NOT_FOUND); } - Map fullMap = new HashMap<>(); - repositories.forEach((key, repository) -> - fullMap.putAll(repository.getAll(nodes.stream().filter(n -> n.getType().equals(key)).map(NodeEntity::getIdNode).collect(Collectors.toSet())))); + + List allNodeInfos = new ArrayList<>(); + repositories.forEach((key, repository) -> allNodeInfos.addAll(repository.getAll( + nodes.stream().filter(n -> n.getType().equals(key)).map(NodeEntity::getIdNode).collect(Collectors.toSet())))); + completeNodeInfos(allNodeInfos, studyId); + Map fullMap = allNodeInfos.stream().collect(Collectors.toMap(AbstractNode::getId, Function.identity())); nodes.stream() - .filter(n -> n.getParentNode() != null) - .forEach(node -> fullMap.get(node.getParentNode().getIdNode()).getChildren().add(fullMap.get(node.getIdNode()))); + .filter(n -> n.getParentNode() != null) + .forEach(node -> fullMap.get(node.getParentNode().getIdNode()).getChildren().add(fullMap.get(node.getIdNode()))); var root = (RootNode) fullMap.get(nodes.stream().filter(n -> n.getType().equals(NodeType.ROOT)).findFirst().orElseThrow(() -> new StudyException(ELEMENT_NOT_FOUND)).getIdNode()); if (root != null) { root.setStudyId(studyId); @@ -425,16 +455,30 @@ public RootNode getStudyTree(UUID studyId) { return root; } + private void completeNodeInfos(List nodes, UUID studyId) { + RootNetworkEntity rootNetworkEntity = rootNetworkRepository.findAllByStudyId(studyId).stream().findFirst().orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND)); + nodes.forEach(nodeInfo -> { + if (nodeInfo instanceof RootNode rootNode) { + rootNode.setReportUuid(rootNetworkEntity.getReportUuid()); + } else { + ((NetworkModificationNode) nodeInfo).completeDtoFromRootNetworkNodeInfo(rootNetworkService.getRootNetworkNodeInfo(nodeInfo.getId(), rootNetworkEntity.getId()).orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND))); + } + }); + } + @Transactional public NetworkModificationNode getStudySubtree(UUID studyId, UUID parentNodeUuid) { List nodes = nodesRepository.findAllByStudyId(studyId); - Map fullMap = new HashMap<>(); - repositories.forEach((key, repository) -> - fullMap.putAll(repository.getAll(nodes.stream().filter(n -> n.getType().equals(key)).map(NodeEntity::getIdNode).collect(Collectors.toSet())))); + + List allNodeInfos = new ArrayList<>(); + repositories.forEach((key, repository) -> allNodeInfos.addAll(repository.getAll( + nodes.stream().filter(n -> n.getType().equals(key)).map(NodeEntity::getIdNode).collect(Collectors.toSet())))); + completeNodeInfos(allNodeInfos, studyId); + Map fullMap = allNodeInfos.stream().collect(Collectors.toMap(AbstractNode::getId, Function.identity())); nodes.stream() - .filter(n -> n.getParentNode() != null) - .forEach(node -> fullMap.get(node.getParentNode().getIdNode()).getChildren().add(fullMap.get(node.getIdNode()))); + .filter(n -> n.getParentNode() != null) + .forEach(node -> fullMap.get(node.getParentNode().getIdNode()).getChildren().add(fullMap.get(node.getIdNode()))); return (NetworkModificationNode) fullMap.get(parentNodeUuid); } @@ -466,7 +510,7 @@ public void cloneStudyTree(AbstractNode nodeToDuplicate, UUID nodeParentId, Stud model.setModificationReports(new HashMap<>(Map.of(model.getId(), newReportUuid))); model.setComputationsReports(new HashMap<>()); - nextParentId = self.createNode(study.getId(), referenceParentNodeId, model, InsertMode.CHILD, null).getId(); + nextParentId = self.createNode(study, referenceParentNodeId, model, InsertMode.CHILD, null).getId(); networkModificationService.createModifications(modificationGroupToDuplicateId, newModificationGroupId); } if (nextParentId != null) { @@ -476,25 +520,70 @@ public void cloneStudyTree(AbstractNode nodeToDuplicate, UUID nodeParentId, Stud } @Transactional - public void createBasicTree(StudyEntity studyEntity, UUID importReportUuid) { - // create 2 nodes : root node, modification node 0 - NodeEntity rootNodeEntity = self.createRoot(studyEntity, importReportUuid); + public void createBasicTree(StudyEntity studyEntity) { + // create 2 nodes : root node, modification node N1 + NodeEntity rootNodeEntity = self.createRoot(studyEntity); NetworkModificationNode modificationNode = NetworkModificationNode .builder() .name("N1") .variantId(FIRST_VARIANT_ID) - .nodeBuildStatus(NodeBuildStatus.from(BuildStatus.BUILT)) + .nodeBuildStatus(NodeBuildStatus.from(BuildStatus.BUILT, BuildStatus.BUILT)) .build(); - self.createNode(studyEntity.getId(), rootNodeEntity.getIdNode(), modificationNode, InsertMode.AFTER, null); + + createNode(studyEntity, rootNodeEntity.getIdNode(), modificationNode, InsertMode.AFTER, null); } @Transactional - public void updateNode(UUID studyUuid, AbstractNode node, String userId) { - NetworkModificationNodeInfoEntity networkModificationNode = networkModificationNodeInfoRepository.findById(node.getId()).orElseThrow(() -> new StudyException(NODE_NOT_FOUND)); - if (!networkModificationNode.getName().equals(node.getName())) { + public void updateNode(UUID studyUuid, NetworkModificationNode node, String userId) { + NetworkModificationNodeInfoEntity networkModificationNodeEntity = networkModificationNodeInfoRepository.findById(node.getId()).orElseThrow(() -> new StudyException(NODE_NOT_FOUND)); + if (!networkModificationNodeEntity.getName().equals(node.getName())) { assertNodeNameNotExist(studyUuid, node.getName()); } - repositories.get(node.getType()).updateNode(node); + + RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = rootNetworkNodeInfoRepository.findAllByNodeInfoId(networkModificationNodeEntity.getId()).stream().findFirst().orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND)); + if (node.getVoltageInitResultUuid() != null) { + rootNetworkNodeInfoEntity.setVoltageInitResultUuid(node.getVoltageInitResultUuid()); + } + if (node.getOneBusShortCircuitAnalysisResultUuid() != null) { + rootNetworkNodeInfoEntity.setOneBusShortCircuitAnalysisResultUuid(node.getOneBusShortCircuitAnalysisResultUuid()); + } + if (node.getShortCircuitAnalysisResultUuid() != null) { + rootNetworkNodeInfoEntity.setShortCircuitAnalysisResultUuid(node.getShortCircuitAnalysisResultUuid()); + } + if (node.getSecurityAnalysisResultUuid() != null) { + rootNetworkNodeInfoEntity.setSecurityAnalysisResultUuid(node.getSecurityAnalysisResultUuid()); + } + if (node.getStateEstimationResultUuid() != null) { + rootNetworkNodeInfoEntity.setStateEstimationResultUuid(node.getStateEstimationResultUuid()); + } + if (node.getNonEvacuatedEnergyResultUuid() != null) { + rootNetworkNodeInfoEntity.setNonEvacuatedEnergyResultUuid(node.getNonEvacuatedEnergyResultUuid()); + } + if (node.getSensitivityAnalysisResultUuid() != null) { + rootNetworkNodeInfoEntity.setSensitivityAnalysisResultUuid(node.getSensitivityAnalysisResultUuid()); + } + if (node.getLoadFlowResultUuid() != null) { + rootNetworkNodeInfoEntity.setLoadFlowResultUuid(node.getLoadFlowResultUuid()); + } + if (node.getNodeBuildStatus() != null) { + rootNetworkNodeInfoEntity.setNodeBuildStatus(node.getNodeBuildStatus().toEntity()); + } + if (node.getVariantId() != null) { + rootNetworkNodeInfoEntity.setVariantId(node.getVariantId()); + } + if (node.getModificationReports() != null) { + rootNetworkNodeInfoEntity.setModificationReports(node.getModificationReports()); + } + if (node.getComputationsReports() != null) { + rootNetworkNodeInfoEntity.setComputationReports(node.getComputationsReports()); + } + if (node.getName() != null) { + networkModificationNodeEntity.setName(node.getName()); + } + if (node.getDescription() != null) { + networkModificationNodeEntity.setDescription(node.getDescription()); + } + if (isRenameNode(node)) { notificationService.emitNodeRenamed(self.getStudyUuidForNodeId(node.getId()), node.getId()); } else { @@ -505,10 +594,10 @@ public void updateNode(UUID studyUuid, AbstractNode node, String userId) { private boolean isRenameNode(AbstractNode node) { NetworkModificationNode renameNode = NetworkModificationNode.builder() - .id(node.getId()) - .name(node.getName()) - .type(node.getType()) - .build(); + .id(node.getId()) + .name(node.getName()) + .type(node.getType()) + .build(); return renameNode.equals(node); } @@ -546,10 +635,10 @@ public boolean isNodeNameExists(UUID studyUuid, String nodeName) { public String getUniqueNodeName(UUID studyUuid) { int counter = 1; List studyNodeNames = networkModificationNodeInfoRepository.findAllByNodeStudyId(studyUuid) - .stream() - .filter(s -> !s.getNode().isStashed()) - .map(AbstractNodeInfoEntity::getName) - .toList(); + .stream() + .filter(s -> !s.getNode().isStashed()) + .map(AbstractNodeInfoEntity::getName) + .toList(); String namePrefix = "N"; String uniqueName = StringUtils.EMPTY; @@ -563,9 +652,9 @@ public String getUniqueNodeName(UUID studyUuid) { private String getSuffixedNodeName(UUID studyUuid, String nodeName) { List studyNodeNames = networkModificationNodeInfoRepository.findAllByNodeStudyId(studyUuid) - .stream() - .map(AbstractNodeInfoEntity::getName) - .toList(); + .stream() + .map(AbstractNodeInfoEntity::getName) + .toList(); String uniqueName = nodeName; int i = 1; @@ -577,13 +666,19 @@ private String getSuffixedNodeName(UUID studyUuid, String nodeName) { } @Transactional - public String getVariantId(UUID nodeUuid) { - return nodesRepository.findById(nodeUuid).map(n -> repositories.get(n.getType()).getVariantId(nodeUuid)).orElseThrow(() -> new StudyException(NODE_NOT_FOUND)); + public String getVariantId(UUID nodeUuid, UUID rootNetworkUuid) { + NodeEntity nodeEntity = nodesRepository.findById(nodeUuid).orElseThrow(() -> new StudyException(NODE_NOT_FOUND)); + // we will use the network initial variant if node is of type ROOT + if (nodeEntity.getType().equals(NodeType.ROOT)) { + return ""; + } + + return rootNetworkNodeInfoRepository.findByNodeInfoIdAndRootNetworkId(nodeUuid, rootNetworkUuid).orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND)).getVariantId(); } @Transactional(readOnly = true) public UUID getModificationGroupUuid(UUID nodeUuid) { - return nodesRepository.findById(nodeUuid).map(n -> repositories.get(n.getType()).getModificationGroupUuid(nodeUuid)).orElseThrow(() -> new StudyException(NODE_NOT_FOUND)); + return networkModificationNodeInfoRepository.findById(nodeUuid).orElseThrow(() -> new StudyException(NODE_NOT_FOUND)).getModificationGroupUuid(); } // Return json string because modification dtos are not available here @@ -602,8 +697,13 @@ public boolean hasModifications(@NonNull UUID nodeUuid, boolean stashed) { } @Transactional - public UUID getReportUuid(UUID nodeUuid) { - return nodesRepository.findById(nodeUuid).map(n -> repositories.get(n.getType()).getReportUuid(nodeUuid)).orElseThrow(() -> new StudyException(NODE_NOT_FOUND)); + public UUID getReportUuid(UUID nodeUuid, UUID rootNetworkUuid) { + NodeEntity nodeEntity = nodesRepository.findById(nodeUuid).orElseThrow(() -> new StudyException(NODE_NOT_FOUND)); + if (nodeEntity.getType().equals(NodeType.ROOT)) { + return rootNetworkRepository.findById(rootNetworkUuid).orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND)).getReportUuid(); + } else { + return rootNetworkService.getRootNetworkNodeInfo(nodeUuid, rootNetworkUuid).orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND)).getModificationReports().get(nodeUuid); + } } @Transactional(readOnly = true) @@ -611,9 +711,37 @@ public List getAllNodesModificationInfos(UUID studyUuid) List nodesModificationInfos = new ArrayList<>(); List nodes = nodesRepository.findAllByStudyId(studyUuid); nodes.forEach(n -> { - NodeModificationInfos nodeModificationInfos = repositories.get(n.getType()).getNodeModificationInfos(n.getIdNode()); - if (nodeModificationInfos != null) { - nodesModificationInfos.add(nodeModificationInfos); + if (n.getType().equals(NodeType.ROOT)) { + rootNetworkRepository.findAllByStudyId(studyUuid).forEach(tp -> { + NodeModificationInfos nodeModificationInfos = NodeModificationInfos.builder() + .id(n.getIdNode()) + .reportUuid(tp.getReportUuid()) + .build(); + + nodesModificationInfos.add(nodeModificationInfos); + }); + } else { + rootNetworkNodeInfoRepository.findAllByNodeInfoId(n.getIdNode()).forEach( + tpNodeInfo -> { + NodeModificationInfos nodeModificationInfos = NodeModificationInfos.builder() + .id(n.getIdNode()) + .reportUuid(tpNodeInfo.getModificationReports().get(n.getIdNode())) + .dynamicSimulationUuid(tpNodeInfo.getDynamicSimulationResultUuid()) + .loadFlowUuid(tpNodeInfo.getLoadFlowResultUuid()) + .nonEvacuatedEnergyUuid(tpNodeInfo.getNonEvacuatedEnergyResultUuid()) + .oneBusShortCircuitAnalysisUuid(tpNodeInfo.getOneBusShortCircuitAnalysisResultUuid()) + .shortCircuitAnalysisUuid(tpNodeInfo.getShortCircuitAnalysisResultUuid()) + .sensitivityAnalysisUuid(tpNodeInfo.getSensitivityAnalysisResultUuid()) + .voltageInitUuid(tpNodeInfo.getVoltageInitResultUuid()) + .stateEstimationUuid(tpNodeInfo.getStateEstimationResultUuid()) + .securityAnalysisUuid(tpNodeInfo.getSecurityAnalysisResultUuid()) + .variantId(tpNodeInfo.getVariantId()) + .modificationGroupUuid(getModificationGroupUuid(n.getIdNode())) + .build(); + + nodesModificationInfos.add(nodeModificationInfos); + } + ); } }); return nodesModificationInfos; @@ -623,11 +751,11 @@ public List> getStashedNodes(UUID studyUuid) { List nodes = nodesRepository.findAllByStudyIdAndStashedAndParentNodeIdNodeOrderByStashDateDesc(studyUuid, true, null); List> result = new ArrayList<>(); repositories.get(NodeType.NETWORK_MODIFICATION).getAllInOrder(nodes.stream().map(NodeEntity::getIdNode).toList()) - .forEach(abstractNode -> { - ArrayList children = new ArrayList<>(); - doGetChildren(abstractNode.getId(), children); - result.add(Pair.of(abstractNode, children.size())); - }); + .forEach(abstractNode -> { + ArrayList children = new ArrayList<>(); + doGetChildren(abstractNode.getId(), children); + result.add(Pair.of(abstractNode, children.size())); + }); return result; } @@ -652,23 +780,23 @@ public void restoreNode(UUID studyId, List nodeIds, UUID anchorNodeId) { } @Transactional - public void updateComputationReportUuid(UUID nodeUuid, ComputationType computationType, UUID reportUuid) { - nodesRepository.findById(nodeUuid).ifPresent(n -> repositories.get(n.getType()).updateComputationReportUuid(nodeUuid, reportUuid, computationType)); + public void updateComputationReportUuid(UUID nodeUuid, UUID rootNetworkUuid, ComputationType computationType, UUID reportUuid) { + rootNetworkService.getRootNetworkNodeInfo(nodeUuid, rootNetworkUuid).ifPresent(tpNodeInfo -> tpNodeInfo.getComputationReports().put(computationType.name(), reportUuid)); } @Transactional - public Map getComputationReports(UUID nodeUuid) { - return nodesRepository.findById(nodeUuid).map(n -> repositories.get(n.getType()).getComputationReports(nodeUuid)).orElseThrow(() -> new StudyException(NODE_NOT_FOUND)); + public Map getComputationReports(UUID nodeUuid, UUID rootNetworkUuid) { + return rootNetworkService.getRootNetworkNodeInfo(nodeUuid, rootNetworkUuid).orElseThrow(() -> new StudyException(NODE_NOT_FOUND)).getComputationReports(); } @Transactional - public void setModificationReports(UUID nodeUuid, Map modificationReports) { - nodesRepository.findById(nodeUuid).ifPresent(n -> repositories.get(n.getType()).setModificationReports(nodeUuid, modificationReports)); + public void setModificationReports(UUID nodeUuid, UUID rootNetworkUuid, Map modificationReports) { + rootNetworkService.getRootNetworkNodeInfo(nodeUuid, rootNetworkUuid).ifPresent(tpNodeInfo -> tpNodeInfo.setModificationReports(modificationReports)); } @Transactional - public Map getModificationReports(UUID nodeUuid) { - return nodesRepository.findById(nodeUuid).map(n -> repositories.get(n.getType()).getModificationReports(nodeUuid)).orElseThrow(() -> new StudyException(NODE_NOT_FOUND)); + public Map getModificationReports(UUID nodeUuid, UUID rootNetworkUuid) { + return rootNetworkService.getRootNetworkNodeInfo(nodeUuid, rootNetworkUuid).orElseThrow(() -> new StudyException(NODE_NOT_FOUND)).getModificationReports(); } private void restoreNodeChildren(UUID studyId, UUID parentNodeId) { @@ -692,32 +820,67 @@ public List getAllNodes(UUID studyUuid) { } @Transactional - public void updateComputationResultUuid(UUID nodeUuid, UUID computationResultUuid, ComputationType computationType) { - nodesRepository.findById(nodeUuid).ifPresent(n -> repositories.get(n.getType()).updateComputationResultUuid(nodeUuid, computationResultUuid, computationType)); + public void updateComputationResultUuid(UUID nodeUuid, UUID rootNetworkUuid, UUID computationResultUuid, ComputationType computationType) { + RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = rootNetworkNodeInfoRepository.findByNodeInfoIdAndRootNetworkId(nodeUuid, rootNetworkUuid).orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND)); + switch (computationType) { + case LOAD_FLOW -> rootNetworkNodeInfoEntity.setLoadFlowResultUuid(computationResultUuid); + case SECURITY_ANALYSIS -> rootNetworkNodeInfoEntity.setSecurityAnalysisResultUuid(computationResultUuid); + case SENSITIVITY_ANALYSIS -> + rootNetworkNodeInfoEntity.setSensitivityAnalysisResultUuid(computationResultUuid); + case NON_EVACUATED_ENERGY_ANALYSIS -> + rootNetworkNodeInfoEntity.setNonEvacuatedEnergyResultUuid(computationResultUuid); + case SHORT_CIRCUIT -> rootNetworkNodeInfoEntity.setShortCircuitAnalysisResultUuid(computationResultUuid); + case SHORT_CIRCUIT_ONE_BUS -> + rootNetworkNodeInfoEntity.setOneBusShortCircuitAnalysisResultUuid(computationResultUuid); + case VOLTAGE_INITIALIZATION -> rootNetworkNodeInfoEntity.setVoltageInitResultUuid(computationResultUuid); + case DYNAMIC_SIMULATION -> rootNetworkNodeInfoEntity.setDynamicSimulationResultUuid(computationResultUuid); + case STATE_ESTIMATION -> rootNetworkNodeInfoEntity.setStateEstimationResultUuid(computationResultUuid); + } } - @Transactional(readOnly = true) - public Optional getComputationResultUuid(UUID nodeUuid, ComputationType computationType) { - return nodesRepository.findById(nodeUuid).map(n -> repositories.get(n.getType()).getComputationResultUuid(nodeUuid, computationType)); + public UUID getComputationResultUuid(UUID nodeUuid, UUID rootNetworkUuid, ComputationType computationType) { + Optional nodeEntity = nodesRepository.findById(nodeUuid); + if (nodeEntity.isEmpty() || nodeEntity.get().getType().equals(NodeType.ROOT)) { + return null; + } + + RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = rootNetworkNodeInfoRepository.findByNodeInfoIdAndRootNetworkId(nodeUuid, rootNetworkUuid).orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND)); + return getComputationResultUuid(rootNetworkNodeInfoEntity, computationType); + } + + public UUID getComputationResultUuid(RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity, ComputationType computationType) { + return switch (computationType) { + case LOAD_FLOW -> rootNetworkNodeInfoEntity.getLoadFlowResultUuid(); + case SECURITY_ANALYSIS -> rootNetworkNodeInfoEntity.getSecurityAnalysisResultUuid(); + case SENSITIVITY_ANALYSIS -> rootNetworkNodeInfoEntity.getSensitivityAnalysisResultUuid(); + case NON_EVACUATED_ENERGY_ANALYSIS -> rootNetworkNodeInfoEntity.getNonEvacuatedEnergyResultUuid(); + case SHORT_CIRCUIT -> rootNetworkNodeInfoEntity.getShortCircuitAnalysisResultUuid(); + case SHORT_CIRCUIT_ONE_BUS -> rootNetworkNodeInfoEntity.getOneBusShortCircuitAnalysisResultUuid(); + case VOLTAGE_INITIALIZATION -> rootNetworkNodeInfoEntity.getVoltageInitResultUuid(); + case DYNAMIC_SIMULATION -> rootNetworkNodeInfoEntity.getDynamicSimulationResultUuid(); + case STATE_ESTIMATION -> rootNetworkNodeInfoEntity.getStateEstimationResultUuid(); + }; } @Transactional(readOnly = true) public List getComputationResultUuids(UUID studyUuid, ComputationType computationType) { List uuids = new ArrayList<>(); List nodes = nodesRepository.findAllByStudyId(studyUuid); - nodes.forEach(n -> { - UUID uuid = repositories.get(n.getType()).getComputationResultUuid(n.getIdNode(), computationType); + nodes.forEach(n -> rootNetworkNodeInfoRepository.findAllByNodeInfoId(n.getIdNode()).forEach(tpNodeInfo -> { + UUID uuid = getComputationResultUuid(tpNodeInfo, computationType); if (uuid != null) { uuids.add(uuid); } - }); + })); return uuids; } private void getSecurityAnalysisResultUuids(UUID nodeUuid, List uuids) { - nodesRepository.findById(nodeUuid).flatMap(n -> Optional.ofNullable(repositories.get(n.getType()).getComputationResultUuid(nodeUuid, SECURITY_ANALYSIS))).ifPresent(uuids::add); - nodesRepository.findAllByParentNodeIdNode(nodeUuid) - .forEach(child -> getSecurityAnalysisResultUuids(child.getIdNode(), uuids)); + rootNetworkNodeInfoRepository.findAllByNodeInfoId(nodeUuid).forEach(tpNodeInfo -> { + nodesRepository.findById(nodeUuid).flatMap(n -> Optional.ofNullable(getComputationResultUuid(tpNodeInfo, SECURITY_ANALYSIS))).ifPresent(uuids::add); + nodesRepository.findAllByParentNodeIdNode(nodeUuid) + .forEach(child -> getSecurityAnalysisResultUuids(child.getIdNode(), uuids)); + }); } @Transactional(readOnly = true) @@ -731,48 +894,48 @@ public List getSecurityAnalysisResultUuidsFromNode(UUID nodeUuid) { public List getShortCircuitResultUuids(UUID studyUuid) { List uuids = new ArrayList<>(); List nodes = nodesRepository.findAllByStudyId(studyUuid); - nodes.forEach(n -> { + nodes.forEach(n -> rootNetworkNodeInfoRepository.findAllByNodeInfoId(n.getIdNode()).forEach(tpNodeInfo -> { // we need to check one bus and all bus - UUID uuidOneBus = repositories.get(n.getType()).getComputationResultUuid(n.getIdNode(), SHORT_CIRCUIT_ONE_BUS); - UUID uuidAllBus = repositories.get(n.getType()).getComputationResultUuid(n.getIdNode(), SHORT_CIRCUIT); + UUID uuidOneBus = getComputationResultUuid(tpNodeInfo, SHORT_CIRCUIT_ONE_BUS); + UUID uuidAllBus = getComputationResultUuid(tpNodeInfo, SHORT_CIRCUIT); if (uuidOneBus != null) { uuids.add(uuidOneBus); } if (uuidAllBus != null) { uuids.add(uuidAllBus); } - }); + })); return uuids; } - private UUID getModificationReportUuid(UUID nodeUuid, UUID nodeToBuildUuid) { - return self.getModificationReports(nodeToBuildUuid).getOrDefault(nodeUuid, UUID.randomUUID()); + private UUID getModificationReportUuid(UUID nodeUuid, UUID rootNetworkUuid, UUID nodeToBuildUuid) { + return self.getModificationReports(nodeToBuildUuid, rootNetworkUuid).getOrDefault(nodeUuid, UUID.randomUUID()); } - private void getBuildInfos(NodeEntity nodeEntity, BuildInfos buildInfos, UUID nodeToBuildUuid) { + private void getBuildInfos(NodeEntity nodeEntity, UUID rootNetworkUuid, BuildInfos buildInfos, UUID nodeToBuildUuid) { AbstractNode node = repositories.get(nodeEntity.getType()).getNode(nodeEntity.getIdNode()); if (node.getType() == NodeType.NETWORK_MODIFICATION) { NetworkModificationNode modificationNode = (NetworkModificationNode) node; if (!modificationNode.getNodeBuildStatus().isBuilt()) { - UUID reportUuid = getModificationReportUuid(nodeEntity.getIdNode(), nodeToBuildUuid); + UUID reportUuid = getModificationReportUuid(nodeEntity.getIdNode(), rootNetworkUuid, nodeToBuildUuid); buildInfos.insertModificationInfos(modificationNode.getModificationGroupUuid(), new ReportInfos(reportUuid, modificationNode.getId())); - getBuildInfos(nodeEntity.getParentNode(), buildInfos, nodeToBuildUuid); + getBuildInfos(nodeEntity.getParentNode(), rootNetworkUuid, buildInfos, nodeToBuildUuid); } else { - buildInfos.setOriginVariantId(self.getVariantId(nodeEntity.getIdNode())); + buildInfos.setOriginVariantId(self.getVariantId(nodeEntity.getIdNode(), rootNetworkUuid)); } } } @Transactional - public BuildInfos getBuildInfos(UUID nodeUuid) { + public BuildInfos getBuildInfos(UUID nodeUuid, UUID rootNetworkUuid) { BuildInfos buildInfos = new BuildInfos(); nodesRepository.findById(nodeUuid).ifPresentOrElse(entity -> { if (entity.getType() != NodeType.NETWORK_MODIFICATION) { // nodeUuid must be a modification node throw new StudyException(BAD_NODE_TYPE, "The node " + entity.getIdNode() + " is not a modification node"); } else { - buildInfos.setDestinationVariantId(self.getVariantId(nodeUuid)); - getBuildInfos(entity, buildInfos, nodeUuid); + buildInfos.setDestinationVariantId(self.getVariantId(nodeUuid, rootNetworkUuid)); + getBuildInfos(entity, rootNetworkUuid, buildInfos, nodeUuid); } }, () -> { throw new StudyException(ELEMENT_NOT_FOUND); @@ -781,164 +944,191 @@ public BuildInfos getBuildInfos(UUID nodeUuid) { return buildInfos; } - private void fillInvalidateNodeInfos(NodeEntity node, InvalidateNodeInfos invalidateNodeInfos, boolean invalidateOnlyChildrenBuildStatus, + private void fillInvalidateNodeInfos(NodeEntity node, UUID rootNetworkUuid, InvalidateNodeInfos invalidateNodeInfos, boolean invalidateOnlyChildrenBuildStatus, boolean deleteVoltageInitResults) { + RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = rootNetworkService.getRootNetworkNodeInfo(node.getIdNode(), rootNetworkUuid).orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND)); if (!invalidateOnlyChildrenBuildStatus) { // we want to delete associated report and variant in this case - repositories.get(node.getType()).getModificationReports(node.getIdNode()).forEach((key, value) -> invalidateNodeInfos.addReportUuid(value)); - invalidateNodeInfos.addVariantId(repositories.get(node.getType()).getVariantId(node.getIdNode())); + rootNetworkNodeInfoEntity.getModificationReports().forEach((key, value) -> invalidateNodeInfos.addReportUuid(value)); + invalidateNodeInfos.addVariantId(self.getVariantId(node.getIdNode(), rootNetworkUuid)); } // we want to delete associated computation reports exept for voltage initialization : only if deleteVoltageInitResults is true - repositories.get(node.getType()).getComputationReports(node.getIdNode()).forEach((key, value) -> { + rootNetworkNodeInfoEntity.getComputationReports().forEach((key, value) -> { if (deleteVoltageInitResults || !VOLTAGE_INITIALIZATION.name().equals(key)) { invalidateNodeInfos.addReportUuid(value); } }); - UUID loadFlowResultUuid = repositories.get(node.getType()).getComputationResultUuid(node.getIdNode(), LOAD_FLOW); + UUID loadFlowResultUuid = getComputationResultUuid(rootNetworkNodeInfoEntity, LOAD_FLOW); if (loadFlowResultUuid != null) { invalidateNodeInfos.addLoadFlowResultUuid(loadFlowResultUuid); } - UUID securityAnalysisResultUuid = repositories.get(node.getType()).getComputationResultUuid(node.getIdNode(), SECURITY_ANALYSIS); + UUID securityAnalysisResultUuid = getComputationResultUuid(rootNetworkNodeInfoEntity, SECURITY_ANALYSIS); if (securityAnalysisResultUuid != null) { invalidateNodeInfos.addSecurityAnalysisResultUuid(securityAnalysisResultUuid); } - UUID sensitivityAnalysisResultUuid = repositories.get(node.getType()).getComputationResultUuid(node.getIdNode(), SENSITIVITY_ANALYSIS); + UUID sensitivityAnalysisResultUuid = getComputationResultUuid(rootNetworkNodeInfoEntity, SENSITIVITY_ANALYSIS); if (sensitivityAnalysisResultUuid != null) { invalidateNodeInfos.addSensitivityAnalysisResultUuid(sensitivityAnalysisResultUuid); } - UUID nonEvacuatedEnergyResultUuid = repositories.get(node.getType()).getComputationResultUuid(node.getIdNode(), NON_EVACUATED_ENERGY_ANALYSIS); + UUID nonEvacuatedEnergyResultUuid = getComputationResultUuid(rootNetworkNodeInfoEntity, NON_EVACUATED_ENERGY_ANALYSIS); if (nonEvacuatedEnergyResultUuid != null) { invalidateNodeInfos.addNonEvacuatedEnergyResultUuid(nonEvacuatedEnergyResultUuid); } - UUID shortCircuitAnalysisResultUuid = repositories.get(node.getType()).getComputationResultUuid(node.getIdNode(), SHORT_CIRCUIT); + UUID shortCircuitAnalysisResultUuid = getComputationResultUuid(rootNetworkNodeInfoEntity, SHORT_CIRCUIT); if (shortCircuitAnalysisResultUuid != null) { invalidateNodeInfos.addShortCircuitAnalysisResultUuid(shortCircuitAnalysisResultUuid); } - UUID oneBusShortCircuitAnalysisResultUuid = repositories.get(node.getType()).getComputationResultUuid(node.getIdNode(), SHORT_CIRCUIT_ONE_BUS); + UUID oneBusShortCircuitAnalysisResultUuid = getComputationResultUuid(rootNetworkNodeInfoEntity, SHORT_CIRCUIT_ONE_BUS); if (oneBusShortCircuitAnalysisResultUuid != null) { invalidateNodeInfos.addOneBusShortCircuitAnalysisResultUuid(oneBusShortCircuitAnalysisResultUuid); } if (deleteVoltageInitResults) { - UUID voltageInitResultUuid = repositories.get(node.getType()).getComputationResultUuid(node.getIdNode(), VOLTAGE_INITIALIZATION); + UUID voltageInitResultUuid = getComputationResultUuid(rootNetworkNodeInfoEntity, VOLTAGE_INITIALIZATION); if (voltageInitResultUuid != null) { invalidateNodeInfos.addVoltageInitResultUuid(voltageInitResultUuid); } } - UUID stateEstimationResultUuid = repositories.get(node.getType()).getComputationResultUuid(node.getIdNode(), STATE_ESTIMATION); + UUID stateEstimationResultUuid = getComputationResultUuid(rootNetworkNodeInfoEntity, STATE_ESTIMATION); if (stateEstimationResultUuid != null) { invalidateNodeInfos.addStateEstimationResultUuid(stateEstimationResultUuid); } } @Transactional - public void invalidateBuild(UUID nodeUuid, boolean invalidateOnlyChildrenBuildStatus, InvalidateNodeInfos invalidateNodeInfos, boolean deleteVoltageInitResults) { + public void invalidateBuild(UUID nodeUuid, UUID rootNetworkUuid, boolean invalidateOnlyChildrenBuildStatus, InvalidateNodeInfos invalidateNodeInfos, boolean deleteVoltageInitResults) { final List changedNodes = new ArrayList<>(); changedNodes.add(nodeUuid); UUID studyId = self.getStudyUuidForNodeId(nodeUuid); - nodesRepository.findById(nodeUuid).ifPresent(n -> { - invalidateNodeProper(n, invalidateNodeInfos, invalidateOnlyChildrenBuildStatus, changedNodes, deleteVoltageInitResults); - invalidateChildrenBuildStatus(n, changedNodes, invalidateNodeInfos, deleteVoltageInitResults); - }); + nodesRepository.findById(nodeUuid).ifPresent(n -> rootNetworkRepository.findById(rootNetworkUuid).ifPresent(tp -> { + invalidateNodeProper(n, tp, invalidateNodeInfos, invalidateOnlyChildrenBuildStatus, changedNodes, deleteVoltageInitResults); + invalidateChildrenBuildStatus(n, tp, changedNodes, invalidateNodeInfos, deleteVoltageInitResults); + })); notificationService.emitNodeBuildStatusUpdated(studyId, changedNodes.stream().distinct().collect(Collectors.toList())); } @Transactional // method used when moving a node to invalidate it without impacting other nodes - public void invalidateBuildOfNodeOnly(UUID nodeUuid, boolean invalidateOnlyChildrenBuildStatus, InvalidateNodeInfos invalidateNodeInfos, boolean deleteVoltageInitResults) { + public void invalidateBuildOfNodeOnly(UUID nodeUuid, UUID rootNetworkUuid, boolean invalidateOnlyChildrenBuildStatus, InvalidateNodeInfos invalidateNodeInfos, boolean deleteVoltageInitResults) { final List changedNodes = new ArrayList<>(); changedNodes.add(nodeUuid); UUID studyId = self.getStudyUuidForNodeId(nodeUuid); nodesRepository.findById(nodeUuid).ifPresent(n -> - invalidateNodeProper(n, invalidateNodeInfos, invalidateOnlyChildrenBuildStatus, changedNodes, deleteVoltageInitResults) + rootNetworkRepository.findById(rootNetworkUuid).ifPresent(tp -> invalidateNodeProper(n, tp, invalidateNodeInfos, invalidateOnlyChildrenBuildStatus, changedNodes, deleteVoltageInitResults)) ); notificationService.emitNodeBuildStatusUpdated(studyId, changedNodes.stream().distinct().collect(Collectors.toList())); } - private void invalidateChildrenBuildStatus(NodeEntity nodeEntity, List changedNodes, InvalidateNodeInfos invalidateNodeInfos, + private void invalidateChildrenBuildStatus(NodeEntity nodeEntity, RootNetworkEntity rootNetworkEntity, List changedNodes, InvalidateNodeInfos invalidateNodeInfos, boolean deleteVoltageInitResults) { nodesRepository.findAllByParentNodeIdNode(nodeEntity.getIdNode()) - .forEach(child -> { - invalidateNodeProper(child, invalidateNodeInfos, false, changedNodes, deleteVoltageInitResults); - invalidateChildrenBuildStatus(child, changedNodes, invalidateNodeInfos, deleteVoltageInitResults); - }); + .forEach(child -> { + invalidateNodeProper(child, rootNetworkEntity, invalidateNodeInfos, false, changedNodes, deleteVoltageInitResults); + invalidateChildrenBuildStatus(child, rootNetworkEntity, changedNodes, invalidateNodeInfos, deleteVoltageInitResults); + }); } - private void invalidateNodeProper(NodeEntity child, InvalidateNodeInfos invalidateNodeInfos, boolean invalidateOnlyChildrenBuildStatus, + private void invalidateNodeProper(NodeEntity child, RootNetworkEntity rootNetworkEntity, InvalidateNodeInfos invalidateNodeInfos, boolean invalidateOnlyChildrenBuildStatus, List changedNodes, boolean deleteVoltageInitResults) { UUID childUuid = child.getIdNode(); // No need to invalidate a node with a status different of "BUILT" - AbstractNodeRepositoryProxy nodeRepository = repositories.get(child.getType()); - if (nodeRepository.getNodeBuildStatus(child.getIdNode()).isBuilt()) { - fillInvalidateNodeInfos(child, invalidateNodeInfos, invalidateOnlyChildrenBuildStatus, deleteVoltageInitResults); + if (self.getNodeBuildStatus(childUuid, rootNetworkEntity.getId()).isBuilt()) { + RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = rootNetworkNodeInfoRepository.findByNodeInfoIdAndRootNetworkId(childUuid, rootNetworkEntity.getId()).orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND)); + fillInvalidateNodeInfos(child, rootNetworkEntity.getId(), invalidateNodeInfos, invalidateOnlyChildrenBuildStatus, deleteVoltageInitResults); if (!invalidateOnlyChildrenBuildStatus) { - nodeRepository.invalidateNodeBuildStatus(childUuid, changedNodes); + invalidateNodeBuildStatus(childUuid, rootNetworkNodeInfoEntity, changedNodes); } - nodeRepository.updateComputationResultUuid(childUuid, null, LOAD_FLOW); - nodeRepository.updateComputationResultUuid(childUuid, null, SECURITY_ANALYSIS); - nodeRepository.updateComputationResultUuid(childUuid, null, SENSITIVITY_ANALYSIS); - nodeRepository.updateComputationResultUuid(childUuid, null, NON_EVACUATED_ENERGY_ANALYSIS); - nodeRepository.updateComputationResultUuid(childUuid, null, SHORT_CIRCUIT); - nodeRepository.updateComputationResultUuid(childUuid, null, SHORT_CIRCUIT_ONE_BUS); - nodeRepository.updateComputationResultUuid(childUuid, null, STATE_ESTIMATION); + + rootNetworkNodeInfoEntity.setLoadFlowResultUuid(null); + rootNetworkNodeInfoEntity.setSecurityAnalysisResultUuid(null); + rootNetworkNodeInfoEntity.setSensitivityAnalysisResultUuid(null); + rootNetworkNodeInfoEntity.setNonEvacuatedEnergyResultUuid(null); + rootNetworkNodeInfoEntity.setShortCircuitAnalysisResultUuid(null); + rootNetworkNodeInfoEntity.setOneBusShortCircuitAnalysisResultUuid(null); if (deleteVoltageInitResults) { - nodeRepository.updateComputationResultUuid(childUuid, null, VOLTAGE_INITIALIZATION); + rootNetworkNodeInfoEntity.setVoltageInitResultUuid(null); } + rootNetworkNodeInfoEntity.setStateEstimationResultUuid(null); + // we want to keep only voltage initialization report if deleteVoltageInitResults is false - Map computationReports = nodeRepository.getComputationReports(childUuid) + Map computationReports = rootNetworkNodeInfoEntity.getComputationReports() .entrySet() .stream() .filter(entry -> VOLTAGE_INITIALIZATION.name().equals(entry.getKey()) && !deleteVoltageInitResults) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); // Update the computation reports in the repository - nodeRepository.setComputationsReports(childUuid, computationReports); + rootNetworkNodeInfoEntity.setComputationReports(computationReports); + } + } + + public void invalidateNodeBuildStatus(UUID nodeUuid, RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity, List changedNodes) { + if (!rootNetworkNodeInfoEntity.getNodeBuildStatus().toDto().isBuilt()) { + return; } + + rootNetworkNodeInfoEntity.setNodeBuildStatus(NodeBuildStatusEmbeddable.from(BuildStatus.NOT_BUILT)); + rootNetworkNodeInfoEntity.setVariantId(UUID.randomUUID().toString()); + rootNetworkNodeInfoEntity.setModificationReports(new HashMap<>(Map.of(nodeUuid, UUID.randomUUID()))); + changedNodes.add(nodeUuid); } @Transactional - public void updateNodeBuildStatus(UUID nodeUuid, NodeBuildStatus nodeBuildStatus) { + public void updateNodeBuildStatus(UUID nodeUuid, UUID rootNetworkUuid, NodeBuildStatus nodeBuildStatus) { List changedNodes = new ArrayList<>(); UUID studyId = self.getStudyUuidForNodeId(nodeUuid); + RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = rootNetworkNodeInfoRepository.findByNodeInfoIdAndRootNetworkId(nodeUuid, rootNetworkUuid).orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND)); NodeEntity nodeEntity = getNodeEntity(nodeUuid); - AbstractNodeRepositoryProxy nodeRepositoryProxy = repositories.get(nodeEntity.getType()); - NodeBuildStatus currentNodeStatus = nodeRepositoryProxy.getNodeBuildStatus(nodeEntity.getIdNode()); + NodeBuildStatusEmbeddable currentNodeStatus = rootNetworkNodeInfoEntity.getNodeBuildStatus(); BuildStatus newGlobalStatus; BuildStatus newLocalStatus; if (nodeBuildStatus.isBuilt()) { newLocalStatus = nodeBuildStatus.getLocalBuildStatus().max(currentNodeStatus.getLocalBuildStatus()); - NodeEntity previousBuiltNode = doGetLastParentNodeBuilt(nodeEntity); - BuildStatus previousGlobalBuildStatus = repositories.get(previousBuiltNode.getType()).getNodeBuildStatus(previousBuiltNode.getIdNode()).getGlobalBuildStatus(); + NodeEntity previousBuiltNode = doGetLastParentNodeBuilt(nodeEntity, rootNetworkUuid); + BuildStatus previousGlobalBuildStatus = getNodeBuildStatus(previousBuiltNode.getIdNode(), rootNetworkUuid).getGlobalBuildStatus(); newGlobalStatus = nodeBuildStatus.getGlobalBuildStatus().max(previousGlobalBuildStatus); } else { newLocalStatus = nodeBuildStatus.getLocalBuildStatus(); newGlobalStatus = nodeBuildStatus.getGlobalBuildStatus(); } - NodeBuildStatus newNodeStatus = NodeBuildStatus.from(newLocalStatus, newGlobalStatus); + NodeBuildStatusEmbeddable newNodeStatus = NodeBuildStatusEmbeddable.builder() + .localBuildStatus(newLocalStatus) + .globalBuildStatus(newGlobalStatus) + .build(); if (newNodeStatus.equals(currentNodeStatus)) { return; } - nodeRepositoryProxy.updateNodeBuildStatus(nodeUuid, newNodeStatus, changedNodes); + rootNetworkNodeInfoEntity.setNodeBuildStatus(newNodeStatus); + changedNodes.add(nodeUuid); notificationService.emitNodeBuildStatusUpdated(studyId, changedNodes); } @Transactional(readOnly = true) - public NodeBuildStatus getNodeBuildStatus(UUID nodeUuid) { - return nodesRepository.findById(nodeUuid).map(n -> repositories.get(n.getType()).getNodeBuildStatus(nodeUuid)).orElse(NodeBuildStatus.from(BuildStatus.NOT_BUILT)); + public NodeBuildStatus getNodeBuildStatus(RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity) { + return rootNetworkNodeInfoEntity.getNodeBuildStatus().toDto(); + } + + @Transactional(readOnly = true) + public NodeBuildStatus getNodeBuildStatus(UUID nodeUuid, UUID rootNetworkUuid) { + NodeEntity nodeEntity = nodesRepository.findById(nodeUuid).orElseThrow(() -> new StudyException(NODE_NOT_FOUND)); + if (nodeEntity.getType().equals(NodeType.ROOT)) { + return NodeBuildStatus.from(BuildStatus.NOT_BUILT); + } + return getNodeBuildStatus(rootNetworkService.getRootNetworkNodeInfo(nodeUuid, rootNetworkUuid).orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND))); } @Transactional(readOnly = true) @@ -948,18 +1138,20 @@ public Optional getParentNodeUuid(UUID nodeUuid) { } @Transactional(readOnly = true) - public UUID doGetLastParentNodeBuiltUuid(UUID nodeUuid) { + public UUID doGetLastParentNodeBuiltUuid(UUID nodeUuid, UUID rootNetworkUuid) { NodeEntity nodeEntity = getNodeEntity(nodeUuid); - return doGetLastParentNodeBuilt(nodeEntity).getIdNode(); + return doGetLastParentNodeBuilt(nodeEntity, rootNetworkUuid).getIdNode(); } - private NodeEntity doGetLastParentNodeBuilt(NodeEntity nodeEntity) { + private NodeEntity doGetLastParentNodeBuilt(NodeEntity nodeEntity, UUID rootNetworkUuid) { if (nodeEntity.getType() == NodeType.ROOT) { return nodeEntity; - } else if (self.getNodeBuildStatus(nodeEntity.getIdNode()).isBuilt()) { + } else if (rootNetworkService + .getRootNetworkNodeInfo(nodeEntity.getIdNode(), rootNetworkUuid).orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND)) + .getNodeBuildStatus().toDto().isBuilt()) { return nodeEntity; } else { - return doGetLastParentNodeBuilt(nodeEntity.getParentNode()); + return doGetLastParentNodeBuilt(nodeEntity.getParentNode(), rootNetworkUuid); } } @@ -981,15 +1173,6 @@ public Optional isReadOnly(UUID nodeUuid) { return nodesRepository.findById(nodeUuid).map(n -> repositories.get(n.getType()).isReadOnly(nodeUuid)); } - @Transactional - public NodeModificationInfos getNodeModificationInfos(UUID nodeUuid) { - NodeModificationInfos nodeModificationInfos = nodesRepository.findById(nodeUuid).map(n -> repositories.get(n.getType()).getNodeModificationInfos(nodeUuid)).orElse(null); - if (nodeModificationInfos == null) { - throw new StudyException(ELEMENT_NOT_FOUND); - } - return nodeModificationInfos; - } - @Transactional(readOnly = true) public List getChildren(UUID id) { List children = new ArrayList<>(); @@ -1000,10 +1183,10 @@ public List getChildren(UUID id) { private void doGetChildren(UUID id, List children) { Optional optNode = nodesRepository.findById(id); optNode.ifPresent(node -> nodesRepository.findAllByParentNodeIdNode(id) - .forEach(child -> { - children.add(child.getIdNode()); - doGetChildren(child.getIdNode(), children); - })); + .forEach(child -> { + children.add(child.getIdNode()); + doGetChildren(child.getIdNode(), children); + })); } // only used for tests @@ -1029,9 +1212,13 @@ private Optional doGetParentNode(UUID nodeUuid, NodeType nodeType) { } } - public long countBuiltNodes(UUID studyUuid) { + public long countBuiltNodes(UUID studyUuid, UUID rootNetworkUuid) { List nodes = nodesRepository.findAllByStudyIdAndTypeAndStashed(studyUuid, NodeType.NETWORK_MODIFICATION, false); // perform N queries, but it's fast: 25 ms for 400 nodes - return nodes.stream().filter(n -> repositories.get(n.getType()).getNodeBuildStatus(n.getIdNode()).isBuilt()).count(); + return nodes.stream().filter(n -> self.getNodeBuildStatus(n.getIdNode(), rootNetworkUuid).isBuilt()).count(); + } + + public NetworkModificationNodeInfoEntity getNetworkModificationNodeInfoEntity(UUID nodeId) { + return networkModificationNodeInfoRepository.findById(nodeId).orElseThrow(() -> new StudyException(ELEMENT_NOT_FOUND)); } } diff --git a/src/main/java/org/gridsuite/study/server/service/NetworkService.java b/src/main/java/org/gridsuite/study/server/service/NetworkService.java index 23d49bcea..9bc0f3bab 100644 --- a/src/main/java/org/gridsuite/study/server/service/NetworkService.java +++ b/src/main/java/org/gridsuite/study/server/service/NetworkService.java @@ -17,8 +17,9 @@ import org.gridsuite.study.server.NetworkVariantsListener; import org.gridsuite.study.server.StudyException; import org.gridsuite.study.server.elasticsearch.EquipmentInfosService; -import org.gridsuite.study.server.repository.StudyEntity; import org.gridsuite.study.server.repository.StudyRepository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkEntity; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkRepository; import org.springframework.context.annotation.ComponentScan; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; @@ -44,13 +45,15 @@ public class NetworkService { private final EquipmentInfosService equipmentInfosService; private final StudyRepository studyRepository; + private final RootNetworkRepository rootNetworkRepository; NetworkService(NetworkStoreService networkStoreService, EquipmentInfosService equipmentInfosService, - StudyRepository studyRepository) { + StudyRepository studyRepository, RootNetworkRepository rootNetworkRepository) { this.networkStoreService = networkStoreService; this.equipmentInfosService = equipmentInfosService; this.studyRepository = studyRepository; + this.rootNetworkRepository = rootNetworkRepository; } public UUID getNetworkUuid(UUID studyUuid) { @@ -84,7 +87,7 @@ public boolean doesNetworkExist(UUID networkUuid) { } UUID doGetNetworkUuid(UUID studyUuid) { - return studyRepository.findById(studyUuid).map(StudyEntity::getNetworkUuid).orElse(null); + return rootNetworkRepository.findAllByStudyId(studyUuid).stream().findFirst().map(RootNetworkEntity::getNetworkUuid).orElse(null); } void deleteNetwork(UUID networkUuid) { diff --git a/src/main/java/org/gridsuite/study/server/service/NonEvacuatedEnergyService.java b/src/main/java/org/gridsuite/study/server/service/NonEvacuatedEnergyService.java index 08e0d699d..7ce2d61d4 100644 --- a/src/main/java/org/gridsuite/study/server/service/NonEvacuatedEnergyService.java +++ b/src/main/java/org/gridsuite/study/server/service/NonEvacuatedEnergyService.java @@ -48,7 +48,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; -import java.util.Optional; import java.util.UUID; import static org.gridsuite.study.server.StudyConstants.DELIMITER; @@ -93,14 +92,14 @@ public void setSensitivityAnalysisServerBaseUri(String sensitivityAnalysisServer this.sensitivityAnalysisServerBaseUri = sensitivityAnalysisServerBaseUri + DELIMITER; } - public void assertNonEvacuatedEnergyNotRunning(UUID nodeUuid) { - String nonEvacuatedEnergyStatus = getNonEvacuatedEnergyStatus(nodeUuid); + public void assertNonEvacuatedEnergyNotRunning(UUID nodeUuid, UUID rootNetworkUuid) { + String nonEvacuatedEnergyStatus = getNonEvacuatedEnergyStatus(nodeUuid, rootNetworkUuid); if (NonEvacuatedEnergyStatus.RUNNING.name().equals(nonEvacuatedEnergyStatus)) { throw new StudyException(NON_EVACUATED_ENERGY_RUNNING); } } - public UUID runNonEvacuatedEnergy(UUID nodeUuid, UUID networkUuid, + public UUID runNonEvacuatedEnergy(UUID nodeUuid, UUID rootNetworkUuid, UUID networkUuid, String variantId, UUID reportUuid, String provider, @@ -109,7 +108,7 @@ public UUID runNonEvacuatedEnergy(UUID nodeUuid, UUID networkUuid, String userId) { String receiver; try { - receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid)), StandardCharsets.UTF_8); + receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid, rootNetworkUuid)), StandardCharsets.UTF_8); } catch (JsonProcessingException e) { throw new UncheckedIOException(e); } @@ -140,16 +139,16 @@ public UUID runNonEvacuatedEnergy(UUID nodeUuid, UUID networkUuid, return restTemplate.exchange(sensitivityAnalysisServerBaseUri + path, HttpMethod.POST, httpEntity, UUID.class).getBody(); } - public String getNonEvacuatedEnergyResult(UUID nodeUuid) { + public String getNonEvacuatedEnergyResult(UUID nodeUuid, UUID rootNetworkUuid) { String result; - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.NON_EVACUATED_ENERGY_ANALYSIS); - if (resultUuidOpt.isEmpty()) { + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.NON_EVACUATED_ENERGY_ANALYSIS); + if (resultUuid == null) { return null; } // initializing from uri string (not from path string) allows build() to escape selector content URI uri = UriComponentsBuilder.fromUriString(sensitivityAnalysisServerBaseUri) - .pathSegment(SENSITIVITY_ANALYSIS_API_VERSION, "non-evacuated-energy", "results", resultUuidOpt.get().toString()) + .pathSegment(SENSITIVITY_ANALYSIS_API_VERSION, "non-evacuated-energy", "results", resultUuid.toString()) .build().encode().toUri(); try { result = restTemplate.getForObject(uri, String.class); @@ -163,16 +162,16 @@ public String getNonEvacuatedEnergyResult(UUID nodeUuid) { return result; } - public String getNonEvacuatedEnergyStatus(UUID nodeUuid) { + public String getNonEvacuatedEnergyStatus(UUID nodeUuid, UUID rootNetworkUuid) { String result; - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.NON_EVACUATED_ENERGY_ANALYSIS); + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.NON_EVACUATED_ENERGY_ANALYSIS); - if (resultUuidOpt.isEmpty()) { + if (resultUuid == null) { return null; } String path = UriComponentsBuilder.fromPath(DELIMITER + SENSITIVITY_ANALYSIS_API_VERSION + "/non-evacuated-energy/results/{resultUuid}/status") - .buildAndExpand(resultUuidOpt.get()).toUriString(); + .buildAndExpand(resultUuid).toUriString(); try { result = restTemplate.getForObject(sensitivityAnalysisServerBaseUri + path, String.class); } catch (HttpStatusCodeException e) { @@ -184,12 +183,12 @@ public String getNonEvacuatedEnergyStatus(UUID nodeUuid) { return result; } - public void stopNonEvacuatedEnergy(UUID studyUuid, UUID nodeUuid, String userId) { + public void stopNonEvacuatedEnergy(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, String userId) { Objects.requireNonNull(studyUuid); Objects.requireNonNull(nodeUuid); - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.NON_EVACUATED_ENERGY_ANALYSIS); - if (resultUuidOpt.isEmpty()) { + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.NON_EVACUATED_ENERGY_ANALYSIS); + if (resultUuid == null) { return; } @@ -199,13 +198,13 @@ public void stopNonEvacuatedEnergy(UUID studyUuid, UUID nodeUuid, String userId) String receiver; try { - receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid)), StandardCharsets.UTF_8); + receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid, rootNetworkUuid)), StandardCharsets.UTF_8); } catch (JsonProcessingException e) { throw new UncheckedIOException(e); } String path = UriComponentsBuilder .fromPath(DELIMITER + SENSITIVITY_ANALYSIS_API_VERSION + "/non-evacuated-energy/results/{resultUuid}/stop") - .queryParam(QUERY_PARAM_RECEIVER, receiver).buildAndExpand(resultUuidOpt.get()).toUriString(); + .queryParam(QUERY_PARAM_RECEIVER, receiver).buildAndExpand(resultUuid).toUriString(); restTemplate.exchange(sensitivityAnalysisServerBaseUri + path, HttpMethod.PUT, new HttpEntity<>(headers), Void.class); } diff --git a/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java b/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java new file mode 100644 index 000000000..5c85f477c --- /dev/null +++ b/src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java @@ -0,0 +1,79 @@ +/** + * 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.NonNull; +import org.gridsuite.study.server.networkmodificationtree.dto.BuildStatus; +import org.gridsuite.study.server.networkmodificationtree.dto.NetworkModificationNode; +import org.gridsuite.study.server.networkmodificationtree.dto.NodeBuildStatus; +import org.gridsuite.study.server.networkmodificationtree.entities.NetworkModificationNodeInfoEntity; +import org.gridsuite.study.server.networkmodificationtree.entities.RootNetworkNodeInfoEntity; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkEntity; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkNodeInfoRepository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkRepository; +import org.springframework.stereotype.Service; + +import java.util.*; + +/** + * @author Slimane amar (Map.of(modificationNodeInfoEntity.getId(), UUID.randomUUID()))); + } + + // For each root network create a link with the node + rootNetworkRepository.findAllByStudyId(studyUuid).forEach(rootNetworkEntity -> { + RootNetworkNodeInfoEntity newRootNetworkNodeInfoEntity = RootNetworkNodeInfoEntity.builder() + .nodeBuildStatus(rootNetworkNodeInfo.getNodeBuildStatus().toEntity()) + .variantId(rootNetworkNodeInfo.getVariantId()) + .dynamicSimulationResultUuid(rootNetworkNodeInfo.getDynamicSimulationResultUuid()) + .loadFlowResultUuid(rootNetworkNodeInfo.getLoadFlowResultUuid()) + .nonEvacuatedEnergyResultUuid(rootNetworkNodeInfo.getNonEvacuatedEnergyResultUuid()) + .securityAnalysisResultUuid(rootNetworkNodeInfo.getSecurityAnalysisResultUuid()) + .sensitivityAnalysisResultUuid(rootNetworkNodeInfo.getSensitivityAnalysisResultUuid()) + .oneBusShortCircuitAnalysisResultUuid(rootNetworkNodeInfo.getOneBusShortCircuitAnalysisResultUuid()) + .shortCircuitAnalysisResultUuid(rootNetworkNodeInfo.getShortCircuitAnalysisResultUuid()) + .stateEstimationResultUuid(rootNetworkNodeInfo.getStateEstimationResultUuid()) + .voltageInitResultUuid(rootNetworkNodeInfo.getVoltageInitResultUuid()) + .computationReports(rootNetworkNodeInfo.getComputationsReports()) + .modificationReports(rootNetworkNodeInfo.getModificationReports()) + .build(); + addLink(modificationNodeInfoEntity, rootNetworkEntity, newRootNetworkNodeInfoEntity); + }); + } + + private void addLink(NetworkModificationNodeInfoEntity nodeInfoEntity, RootNetworkEntity rootNetworkEntity, RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity) { + nodeInfoEntity.addRootNetworkNodeInfo(rootNetworkNodeInfoEntity); + rootNetworkEntity.addRootNetworkNodeInfo(rootNetworkNodeInfoEntity); + rootNetworkNodeInfoRepository.save(rootNetworkNodeInfoEntity); + } +} diff --git a/src/main/java/org/gridsuite/study/server/service/RootNetworkService.java b/src/main/java/org/gridsuite/study/server/service/RootNetworkService.java new file mode 100644 index 000000000..44d308b01 --- /dev/null +++ b/src/main/java/org/gridsuite/study/server/service/RootNetworkService.java @@ -0,0 +1,85 @@ +/* + * 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.NonNull; +import org.gridsuite.study.server.dto.CaseInfos; +import org.gridsuite.study.server.dto.NetworkInfos; +import org.gridsuite.study.server.networkmodificationtree.entities.RootNetworkNodeInfoEntity; +import org.gridsuite.study.server.repository.StudyEntity; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkEntity; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkNodeInfoRepository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Stream; + +/** + * @author Le Saulnier Kevin + */ +@Service +public class RootNetworkService { + private final RootNetworkNodeInfoRepository rootNetworkNodeInfoRepository; + private final RootNetworkRepository rootNetworkRepository; + private final RootNetworkNodeInfoService rootNetworkNodeInfoService; + + public RootNetworkService(RootNetworkNodeInfoRepository rootNetworkNodeInfoRepository, RootNetworkRepository rootNetworkRepository, + RootNetworkNodeInfoService rootNetworkNodeInfoService) { + this.rootNetworkNodeInfoRepository = rootNetworkNodeInfoRepository; + this.rootNetworkRepository = rootNetworkRepository; + this.rootNetworkNodeInfoService = rootNetworkNodeInfoService; + } + + public UUID getNetworkUuid(UUID rootNetworkUuid) { + return rootNetworkRepository.findById(rootNetworkUuid).map(RootNetworkEntity::getNetworkUuid).orElse(null); + } + + @Transactional + public void createRootNetwork(@NonNull StudyEntity studyEntity, @NonNull NetworkInfos networkInfos, @NonNull CaseInfos caseInfos, @NonNull UUID importReportUuid) { + RootNetworkEntity rootNetworkEntity = rootNetworkRepository.save(RootNetworkEntity.builder() + .networkUuid(networkInfos.getNetworkUuid()) + .networkId(networkInfos.getNetworkId()) + .caseFormat(caseInfos.getCaseFormat()) + .caseUuid(caseInfos.getCaseUuid()) + .caseName(caseInfos.getCaseName()) + .reportUuid(importReportUuid) + .build() + ); + + studyEntity.addRootNetwork(rootNetworkEntity); + + rootNetworkNodeInfoService.createRootNetworkLinks(Objects.requireNonNull(studyEntity.getId()), rootNetworkEntity); + } + + // TODO move to RootNetworkNodeLinkService + public Optional getRootNetworkNodeInfo(UUID nodeUuid, UUID rootNetworkUuid) { + return rootNetworkNodeInfoRepository.findByNodeInfoIdAndRootNetworkId(nodeUuid, rootNetworkUuid); + } + + // TODO move to study service + public List getAllReportUuids(UUID studyUuid) { + List rootNetworkEntities = rootNetworkRepository.findAllWithInfosByStudyId(studyUuid); + List rootNodeReportUuids = rootNetworkEntities.stream().map(RootNetworkEntity::getReportUuid).toList(); + List rootNetworkNodeInfoEntities = rootNetworkEntities.stream().flatMap(rootNetworkEntity -> rootNetworkEntity.getRootNetworkNodeInfos().stream()).toList(); + + //study reports uuids is the concatenation of modification reports, computation reports and root reports uuids + + List networkModificationNodeReportUuids = rootNetworkNodeInfoEntities.stream().flatMap(rootNetworkNodeInfoEntity -> + Stream.of( + rootNetworkNodeInfoEntity.getModificationReports().values().stream(), + rootNetworkNodeInfoEntity.getComputationReports().values().stream())) + .reduce(Stream::concat) + .orElse(Stream.empty()).toList(); + + return Stream.concat(rootNodeReportUuids.stream(), networkModificationNodeReportUuids.stream()).toList(); + } +} diff --git a/src/main/java/org/gridsuite/study/server/service/SecurityAnalysisService.java b/src/main/java/org/gridsuite/study/server/service/SecurityAnalysisService.java index c4abaa4e8..941200f33 100644 --- a/src/main/java/org/gridsuite/study/server/service/SecurityAnalysisService.java +++ b/src/main/java/org/gridsuite/study/server/service/SecurityAnalysisService.java @@ -30,7 +30,6 @@ import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Objects; -import java.util.Optional; import java.util.UUID; import static org.gridsuite.study.server.StudyConstants.*; @@ -66,11 +65,11 @@ public SecurityAnalysisService(RemoteServicesProperties remoteServicesProperties this.restTemplate = restTemplate; } - public String getSecurityAnalysisResult(UUID nodeUuid, SecurityAnalysisResultType resultType, String filters, Pageable pageable) { + public String getSecurityAnalysisResult(UUID nodeUuid, UUID rootNetworkUuid, SecurityAnalysisResultType resultType, String filters, Pageable pageable) { String result; - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.SECURITY_ANALYSIS); + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.SECURITY_ANALYSIS); - if (resultUuidOpt.isEmpty()) { + if (resultUuid == null) { return null; } @@ -86,7 +85,7 @@ public String getSecurityAnalysisResult(UUID nodeUuid, SecurityAnalysisResultTyp pathBuilder.queryParam("sort", order.getProperty() + "," + order.getDirection()); } - String path = pathBuilder.buildAndExpand(resultUuidOpt.get()).toUriString(); + String path = pathBuilder.buildAndExpand(resultUuid).toUriString(); try { result = restTemplate.getForObject(securityAnalysisServerBaseUri + path, String.class); @@ -101,17 +100,17 @@ public String getSecurityAnalysisResult(UUID nodeUuid, SecurityAnalysisResultTyp return result; } - public byte[] getSecurityAnalysisResultCsv(UUID nodeUuid, SecurityAnalysisResultType resultType, String csvTranslations) { + public byte[] getSecurityAnalysisResultCsv(UUID nodeUuid, UUID rootNetworkUuid, SecurityAnalysisResultType resultType, String csvTranslations) { ResponseEntity result; - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.SECURITY_ANALYSIS); + UUID resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.SECURITY_ANALYSIS); - if (resultUuidOpt.isEmpty()) { + if (resultUuidOpt == null) { throw new StudyException(SECURITY_ANALYSIS_NOT_FOUND); } UriComponentsBuilder pathBuilder = UriComponentsBuilder.fromPath(DELIMITER + SECURITY_ANALYSIS_API_VERSION + "/results/{resultUuid}/" + getExportPathFromResultType(resultType)); - String path = pathBuilder.buildAndExpand(resultUuidOpt.get()).toUriString(); + String path = pathBuilder.buildAndExpand(resultUuidOpt).toUriString(); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); @@ -173,20 +172,20 @@ public UUID runSecurityAnalysis(UUID networkUuid, String variantId, RunSecurityA .exchange(securityAnalysisServerBaseUri + path, HttpMethod.POST, httpEntity, UUID.class).getBody(); } - public void stopSecurityAnalysis(UUID studyUuid, UUID nodeUuid, String userId) { + public void stopSecurityAnalysis(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, String userId) { Objects.requireNonNull(studyUuid); Objects.requireNonNull(nodeUuid); Objects.requireNonNull(userId); - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.SECURITY_ANALYSIS); + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.SECURITY_ANALYSIS); - if (resultUuidOpt.isEmpty()) { + if (resultUuid == null) { return; } String receiver; try { - receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid)), + receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid, rootNetworkUuid)), StandardCharsets.UTF_8); } catch (JsonProcessingException e) { throw new UncheckedIOException(e); @@ -194,7 +193,7 @@ public void stopSecurityAnalysis(UUID studyUuid, UUID nodeUuid, String userId) { String path = UriComponentsBuilder .fromPath(DELIMITER + SECURITY_ANALYSIS_API_VERSION + "/results/{resultUuid}/stop") - .queryParam(QUERY_PARAM_RECEIVER, receiver).buildAndExpand(resultUuidOpt.get()).toUriString(); + .queryParam(QUERY_PARAM_RECEIVER, receiver).buildAndExpand(resultUuid).toUriString(); HttpHeaders headers = new HttpHeaders(); headers.set(HEADER_USER_ID, userId); @@ -203,18 +202,18 @@ public void stopSecurityAnalysis(UUID studyUuid, UUID nodeUuid, String userId) { restTemplate.exchange(securityAnalysisServerBaseUri + path, HttpMethod.PUT, new HttpEntity<>(headers), Void.class); } - public SecurityAnalysisStatus getSecurityAnalysisStatus(UUID nodeUuid) { + public SecurityAnalysisStatus getSecurityAnalysisStatus(UUID nodeUuid, UUID rootNetworkUuid) { SecurityAnalysisStatus status; - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.SECURITY_ANALYSIS); + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.SECURITY_ANALYSIS); - if (resultUuidOpt.isEmpty()) { + if (resultUuid == null) { return null; } try { String path = UriComponentsBuilder .fromPath(DELIMITER + SECURITY_ANALYSIS_API_VERSION + "/results/{resultUuid}/status") - .buildAndExpand(resultUuidOpt.get()).toUriString(); + .buildAndExpand(resultUuid).toUriString(); status = restTemplate.getForObject(securityAnalysisServerBaseUri + path, SecurityAnalysisStatus.class); } catch (HttpStatusCodeException e) { @@ -260,8 +259,8 @@ public void invalidateSaStatus(List uuids) { } } - public void assertSecurityAnalysisNotRunning(UUID nodeUuid) { - SecurityAnalysisStatus sas = getSecurityAnalysisStatus(nodeUuid); + public void assertSecurityAnalysisNotRunning(UUID nodeUuid, UUID rootNetworkUuid) { + SecurityAnalysisStatus sas = getSecurityAnalysisStatus(nodeUuid, rootNetworkUuid); if (sas == SecurityAnalysisStatus.RUNNING) { throw new StudyException(SECURITY_ANALYSIS_RUNNING); } diff --git a/src/main/java/org/gridsuite/study/server/service/SensitivityAnalysisService.java b/src/main/java/org/gridsuite/study/server/service/SensitivityAnalysisService.java index c0572eab9..721ef3d9d 100644 --- a/src/main/java/org/gridsuite/study/server/service/SensitivityAnalysisService.java +++ b/src/main/java/org/gridsuite/study/server/service/SensitivityAnalysisService.java @@ -30,7 +30,6 @@ import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Objects; -import java.util.Optional; import java.util.UUID; import static org.gridsuite.study.server.StudyConstants.*; @@ -70,7 +69,7 @@ public void setSensitivityAnalysisServerBaseUri(String sensitivityAnalysisServer this.sensitivityAnalysisServerBaseUri = sensitivityAnalysisServerBaseUri + DELIMITER; } - public UUID runSensitivityAnalysis(UUID nodeUuid, UUID networkUuid, + public UUID runSensitivityAnalysis(UUID nodeUuid, UUID rootNetworkUuid, UUID networkUuid, String variantId, UUID reportUuid, String userId, @@ -78,7 +77,7 @@ public UUID runSensitivityAnalysis(UUID nodeUuid, UUID networkUuid, UUID loadFlowParametersUuid) { String receiver; try { - receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid)), StandardCharsets.UTF_8); + receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid, rootNetworkUuid)), StandardCharsets.UTF_8); } catch (JsonProcessingException e) { throw new UncheckedIOException(e); } @@ -109,16 +108,16 @@ public UUID runSensitivityAnalysis(UUID nodeUuid, UUID networkUuid, return restTemplate.exchange(sensitivityAnalysisServerBaseUri + path, HttpMethod.POST, httpEntity, UUID.class).getBody(); } - public String getSensitivityAnalysisResult(UUID nodeUuid, String selector) { + public String getSensitivityAnalysisResult(UUID nodeUuid, UUID rootNetworkUuid, String selector) { String result; - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.SENSITIVITY_ANALYSIS); - if (resultUuidOpt.isEmpty()) { + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.SENSITIVITY_ANALYSIS); + if (resultUuid == null) { return null; } // initializing from uri string (not from path string) allows build() to escape selector content URI uri = UriComponentsBuilder.fromUriString(sensitivityAnalysisServerBaseUri) - .pathSegment(SENSITIVITY_ANALYSIS_API_VERSION, RESULTS, resultUuidOpt.get().toString()) + .pathSegment(SENSITIVITY_ANALYSIS_API_VERSION, RESULTS, resultUuid.toString()) .queryParam("selector", selector).build().encode().toUri(); try { result = restTemplate.getForObject(uri, String.class); @@ -132,15 +131,15 @@ public String getSensitivityAnalysisResult(UUID nodeUuid, String selector) { return result; } - public byte[] exportSensitivityResultsAsCsv(UUID nodeUuid, SensitivityAnalysisCsvFileInfos sensitivityAnalysisCsvFileInfos) { - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.SENSITIVITY_ANALYSIS); - if (resultUuidOpt.isEmpty()) { + public byte[] exportSensitivityResultsAsCsv(UUID nodeUuid, UUID rootNetworkUuid, SensitivityAnalysisCsvFileInfos sensitivityAnalysisCsvFileInfos) { + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.SENSITIVITY_ANALYSIS); + if (resultUuid == null) { throw new StudyException(SENSITIVITY_ANALYSIS_NOT_FOUND); } // initializing from uri string (not from path string) allows build() to escape selector content URI uri = UriComponentsBuilder.fromUriString(sensitivityAnalysisServerBaseUri) - .pathSegment(SENSITIVITY_ANALYSIS_API_VERSION, RESULTS, resultUuidOpt.get().toString(), "csv") + .pathSegment(SENSITIVITY_ANALYSIS_API_VERSION, RESULTS, resultUuid.toString(), "csv") .build() .encode() .toUri(); @@ -161,16 +160,16 @@ public byte[] exportSensitivityResultsAsCsv(UUID nodeUuid, SensitivityAnalysisCs } - public String getSensitivityResultsFilterOptions(UUID nodeUuid, String selector) { + public String getSensitivityResultsFilterOptions(UUID nodeUuid, UUID rootNetworkUuid, String selector) { String options; - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.SENSITIVITY_ANALYSIS); - if (resultUuidOpt.isEmpty()) { + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.SENSITIVITY_ANALYSIS); + if (resultUuid == null) { return null; } // initializing from uri string (not from path string) allows build() to escape selector content URI uri = UriComponentsBuilder.fromUriString(sensitivityAnalysisServerBaseUri) - .pathSegment(SENSITIVITY_ANALYSIS_API_VERSION, RESULTS, resultUuidOpt.get().toString(), "filter-options") + .pathSegment(SENSITIVITY_ANALYSIS_API_VERSION, RESULTS, resultUuid.toString(), "filter-options") .queryParam("selector", selector).build().encode().toUri(); try { options = restTemplate.getForObject(uri, String.class); @@ -184,16 +183,16 @@ public String getSensitivityResultsFilterOptions(UUID nodeUuid, String selector) return options; } - public String getSensitivityAnalysisStatus(UUID nodeUuid) { + public String getSensitivityAnalysisStatus(UUID nodeUuid, UUID rootNetworkUuid) { String result; - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.SENSITIVITY_ANALYSIS); + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.SENSITIVITY_ANALYSIS); - if (resultUuidOpt.isEmpty()) { + if (resultUuid == null) { return null; } String path = UriComponentsBuilder.fromPath(DELIMITER + SENSITIVITY_ANALYSIS_API_VERSION + "/results/{resultUuid}/status") - .buildAndExpand(resultUuidOpt.get()).toUriString(); + .buildAndExpand(resultUuid).toUriString(); try { result = restTemplate.getForObject(sensitivityAnalysisServerBaseUri + path, String.class); } catch (HttpStatusCodeException e) { @@ -205,25 +204,25 @@ public String getSensitivityAnalysisStatus(UUID nodeUuid) { return result; } - public void stopSensitivityAnalysis(UUID studyUuid, UUID nodeUuid, String userId) { + public void stopSensitivityAnalysis(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, String userId) { Objects.requireNonNull(studyUuid); Objects.requireNonNull(nodeUuid); Objects.requireNonNull(userId); - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.SENSITIVITY_ANALYSIS); - if (resultUuidOpt.isEmpty()) { + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.SENSITIVITY_ANALYSIS); + if (resultUuid == null) { return; } String receiver; try { - receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid)), StandardCharsets.UTF_8); + receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid, rootNetworkUuid)), StandardCharsets.UTF_8); } catch (JsonProcessingException e) { throw new UncheckedIOException(e); } String path = UriComponentsBuilder .fromPath(DELIMITER + SENSITIVITY_ANALYSIS_API_VERSION + "/results/{resultUuid}/stop") - .queryParam(QUERY_PARAM_RECEIVER, receiver).buildAndExpand(resultUuidOpt.get()).toUriString(); + .queryParam(QUERY_PARAM_RECEIVER, receiver).buildAndExpand(resultUuid).toUriString(); HttpHeaders headers = new HttpHeaders(); headers.set(HEADER_USER_ID, userId); @@ -266,8 +265,8 @@ public Integer getSensitivityAnalysisResultsCount() { return restTemplate.getForObject(sensitivityAnalysisServerBaseUri + path, Integer.class); } - public void assertSensitivityAnalysisNotRunning(UUID nodeUuid) { - String sas = getSensitivityAnalysisStatus(nodeUuid); + public void assertSensitivityAnalysisNotRunning(UUID nodeUuid, UUID rootNetworkUuid) { + String sas = getSensitivityAnalysisStatus(nodeUuid, rootNetworkUuid); if (SensitivityAnalysisStatus.RUNNING.name().equals(sas)) { throw new StudyException(SENSITIVITY_ANALYSIS_RUNNING); } diff --git a/src/main/java/org/gridsuite/study/server/service/StateEstimationService.java b/src/main/java/org/gridsuite/study/server/service/StateEstimationService.java index 856b166c9..7cbecb172 100644 --- a/src/main/java/org/gridsuite/study/server/service/StateEstimationService.java +++ b/src/main/java/org/gridsuite/study/server/service/StateEstimationService.java @@ -31,7 +31,6 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.Objects; -import java.util.Optional; import java.util.UUID; import static org.gridsuite.study.server.StudyConstants.DELIMITER; @@ -71,16 +70,16 @@ public StateEstimationService(RemoteServicesProperties remoteServicesProperties, this.restTemplate = restTemplate; } - public String getStateEstimationResult(UUID nodeUuid) { + public String getStateEstimationResult(UUID nodeUuid, UUID rootNetworkUuid) { String result; - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.STATE_ESTIMATION); + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.STATE_ESTIMATION); - if (resultUuidOpt.isEmpty()) { + if (resultUuid == null) { return null; } UriComponentsBuilder pathBuilder = UriComponentsBuilder.fromPath(DELIMITER + STATE_ESTIMATION_API_VERSION + "/results/{resultUuid}"); - String path = pathBuilder.buildAndExpand(resultUuidOpt.get()).toUriString(); + String path = pathBuilder.buildAndExpand(resultUuid).toUriString(); try { result = restTemplate.getForObject(stateEstimationServerServerBaseUri + path, String.class); @@ -115,40 +114,40 @@ public UUID runStateEstimation(UUID networkUuid, String variantId, ReportInfos r return restTemplate.exchange(stateEstimationServerServerBaseUri + path, HttpMethod.POST, httpEntity, UUID.class).getBody(); } - public void stopStateEstimation(UUID studyUuid, UUID nodeUuid) { + public void stopStateEstimation(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid) { Objects.requireNonNull(studyUuid); Objects.requireNonNull(nodeUuid); - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.STATE_ESTIMATION); + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.STATE_ESTIMATION); - if (resultUuidOpt.isEmpty()) { + if (resultUuid == null) { return; } String receiver; try { - receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid)), StandardCharsets.UTF_8); + receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid, rootNetworkUuid)), StandardCharsets.UTF_8); } catch (JsonProcessingException e) { throw new UncheckedIOException(e); } String path = UriComponentsBuilder .fromPath(DELIMITER + STATE_ESTIMATION_API_VERSION + "/results/{resultUuid}/stop") - .queryParam(QUERY_PARAM_RECEIVER, receiver).buildAndExpand(resultUuidOpt.get()).toUriString(); + .queryParam(QUERY_PARAM_RECEIVER, receiver).buildAndExpand(resultUuid).toUriString(); restTemplate.put(stateEstimationServerServerBaseUri + path, Void.class); } - public String getStateEstimationStatus(UUID nodeUuid) { - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.STATE_ESTIMATION); - if (resultUuidOpt.isEmpty()) { + public String getStateEstimationStatus(UUID nodeUuid, UUID rootNetworkUuid) { + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.STATE_ESTIMATION); + if (resultUuid == null) { return null; } String status; try { String path = UriComponentsBuilder .fromPath(DELIMITER + STATE_ESTIMATION_API_VERSION + "/results/{resultUuid}/status") - .buildAndExpand(resultUuidOpt.get()).toUriString(); + .buildAndExpand(resultUuid).toUriString(); status = restTemplate.getForObject(stateEstimationServerServerBaseUri + path, String.class); } catch (HttpStatusCodeException e) { if (HttpStatus.NOT_FOUND.equals(e.getStatusCode())) { @@ -182,8 +181,8 @@ public Integer getStateEstimationResultsCount() { return restTemplate.getForObject(stateEstimationServerServerBaseUri + path, Integer.class); } - public void assertStateEstimationNotRunning(UUID nodeUuid) { - String status = getStateEstimationStatus(nodeUuid); + public void assertStateEstimationNotRunning(UUID nodeUuid, UUID rootNetworkUuid) { + String status = getStateEstimationStatus(nodeUuid, rootNetworkUuid); if (StateEstimationStatus.RUNNING.name().equals(status)) { throw new StudyException(STATE_ESTIMATION_RUNNING); } diff --git a/src/main/java/org/gridsuite/study/server/service/StudyService.java b/src/main/java/org/gridsuite/study/server/service/StudyService.java index 8a5698909..9df9c8d75 100644 --- a/src/main/java/org/gridsuite/study/server/service/StudyService.java +++ b/src/main/java/org/gridsuite/study/server/service/StudyService.java @@ -32,16 +32,18 @@ import org.gridsuite.study.server.dto.voltageinit.parameters.VoltageInitParametersInfos; import org.gridsuite.study.server.elasticsearch.EquipmentInfosService; import org.gridsuite.study.server.elasticsearch.StudyInfosService; -import org.gridsuite.study.server.networkmodificationtree.dto.AbstractNode; -import org.gridsuite.study.server.networkmodificationtree.dto.BuildStatus; -import org.gridsuite.study.server.networkmodificationtree.dto.InsertMode; -import org.gridsuite.study.server.networkmodificationtree.dto.NodeBuildStatus; +import org.gridsuite.study.server.networkmodificationtree.dto.*; +import org.gridsuite.study.server.networkmodificationtree.entities.NetworkModificationNodeInfoEntity; import org.gridsuite.study.server.networkmodificationtree.entities.NodeEntity; +import org.gridsuite.study.server.networkmodificationtree.entities.RootNetworkNodeInfoEntity; import org.gridsuite.study.server.networkmodificationtree.entities.NodeType; import org.gridsuite.study.server.notification.NotificationService; import org.gridsuite.study.server.notification.dto.NetworkImpactsInfos; import org.gridsuite.study.server.repository.*; import org.gridsuite.study.server.repository.nonevacuatedenergy.NonEvacuatedEnergyParametersEntity; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkEntity; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkNodeInfoRepository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkRepository; import org.gridsuite.study.server.repository.voltageinit.StudyVoltageInitParametersEntity; import org.gridsuite.study.server.service.dynamicsimulation.DynamicSimulationEventService; import org.gridsuite.study.server.service.dynamicsimulation.DynamicSimulationService; @@ -68,7 +70,6 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import java.util.stream.Collectors; -import java.util.stream.Stream; import static org.gridsuite.study.server.StudyException.Type.*; import static org.gridsuite.study.server.dto.ComputationType.*; @@ -85,6 +86,8 @@ public class StudyService { private static final Logger LOGGER = LoggerFactory.getLogger(StudyService.class); + private final RootNetworkService rootNetworkService; + private final RootNetworkNodeInfoRepository rootNetworkNodeInfoRepository; NotificationService notificationService; @@ -120,6 +123,7 @@ public class StudyService { private final ActionsService actionsService; private final CaseService caseService; private final StateEstimationService stateEstimationService; + private final RootNetworkRepository rootNetworkRepository; private final ObjectMapper objectMapper; @@ -176,7 +180,8 @@ public StudyService( DynamicSimulationEventService dynamicSimulationEventService, FilterService filterService, StateEstimationService stateEstimationService, - @Lazy StudyService studyService) { + RootNetworkRepository rootNetworkRepository, + @Lazy StudyService studyService, RootNetworkService rootNetworkService, RootNetworkNodeInfoRepository rootNetworkNodeInfoRepository) { this.defaultNonEvacuatedEnergyProvider = defaultNonEvacuatedEnergyProvider; this.defaultDynamicSimulationProvider = defaultDynamicSimulationProvider; this.studyRepository = studyRepository; @@ -208,12 +213,15 @@ public StudyService( this.filterService = filterService; this.stateEstimationService = stateEstimationService; this.self = studyService; + this.rootNetworkRepository = rootNetworkRepository; + this.rootNetworkService = rootNetworkService; + this.rootNetworkNodeInfoRepository = rootNetworkNodeInfoRepository; } private static CreatedStudyBasicInfos toStudyInfos(StudyEntity entity) { return CreatedStudyBasicInfos.builder() .id(entity.getId()) - .caseFormat(entity.getCaseFormat()) + .caseFormat(entity.getFirstRootNetwork().getCaseFormat()) .build(); } @@ -223,22 +231,23 @@ private static BasicStudyInfos toBasicStudyInfos(StudyCreationRequestEntity enti .build(); } - private static CreatedStudyBasicInfos toCreatedStudyBasicInfos(StudyEntity entity) { + private CreatedStudyBasicInfos toCreatedStudyBasicInfos(StudyEntity entity) { + RootNetworkEntity firstRootNetworkEntity = rootNetworkRepository.findAllByStudyId(entity.getId()).stream().findFirst().orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND)); return CreatedStudyBasicInfos.builder() .id(entity.getId()) - .caseFormat(entity.getCaseFormat()) + .caseFormat(firstRootNetworkEntity.getCaseFormat()) .build(); } public List getStudies() { return studyRepository.findAll().stream() - .map(StudyService::toCreatedStudyBasicInfos) + .map(this::toCreatedStudyBasicInfos) .collect(Collectors.toList()); } public List getStudiesNetworkUuids() { return studyRepository.findAll().stream() - .map(StudyEntity::getNetworkUuid) + .map(study -> study.getFirstRootNetwork().getNetworkUuid()) .toList(); } @@ -249,11 +258,11 @@ public List getAllOrphanIndexedEquipmentsNetworkUuids() { public String getStudyCaseName(UUID studyUuid) { Objects.requireNonNull(studyUuid); StudyEntity study = studyRepository.findById(studyUuid).orElseThrow(() -> new StudyException(STUDY_NOT_FOUND)); - return study != null ? study.getCaseName() : ""; + return study != null ? study.getFirstRootNetwork().getCaseName() : ""; } public List getStudiesMetadata(List uuids) { - return studyRepository.findAllById(uuids).stream().map(StudyService::toCreatedStudyBasicInfos) + return studyRepository.findAllById(uuids).stream().map(this::toCreatedStudyBasicInfos) .collect(Collectors.toList()); } @@ -356,48 +365,30 @@ public CreatedStudyBasicInfos getStudyInfos(UUID studyUuid) { @Transactional(readOnly = true) public UUID getStudyCaseUuid(UUID studyUuid) { - return studyRepository.findById(studyUuid).orElseThrow(() -> new StudyException(STUDY_NOT_FOUND)).getCaseUuid(); + return studyRepository.findById(studyUuid).orElseThrow(() -> new StudyException(STUDY_NOT_FOUND)).getFirstRootNetwork().getCaseUuid(); } public List searchStudies(@NonNull String query) { return studyInfosService.search(query); } - private UUID getNodeUuidToSearchIn(UUID initialNodeUuid, boolean inUpstreamBuiltParentNode) { + private UUID getNodeUuidToSearchIn(UUID initialNodeUuid, UUID rootNetworkUuid, boolean inUpstreamBuiltParentNode) { UUID nodeUuidToSearchIn = initialNodeUuid; if (inUpstreamBuiltParentNode) { - nodeUuidToSearchIn = networkModificationTreeService.doGetLastParentNodeBuiltUuid(initialNodeUuid); + nodeUuidToSearchIn = networkModificationTreeService.doGetLastParentNodeBuiltUuid(initialNodeUuid, rootNetworkUuid); } return nodeUuidToSearchIn; } - public List searchEquipments(@NonNull UUID studyUuid, @NonNull UUID nodeUuid, @NonNull String userInput, + public List searchEquipments(@NonNull UUID nodeUuid, @NonNull UUID rootNetworkUuid, @NonNull String userInput, @NonNull EquipmentInfosService.FieldSelector fieldSelector, String equipmentType, boolean inUpstreamBuiltParentNode) { - UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, inUpstreamBuiltParentNode); - UUID networkUuid = networkStoreService.getNetworkUuid(studyUuid); - String variantId = networkModificationTreeService.getVariantId(nodeUuidToSearchIn); + UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, rootNetworkUuid, inUpstreamBuiltParentNode); + UUID networkUuid = rootNetworkService.getNetworkUuid(rootNetworkUuid); + String variantId = networkModificationTreeService.getVariantId(nodeUuidToSearchIn, rootNetworkUuid); return equipmentInfosService.searchEquipments(networkUuid, variantId, userInput, fieldSelector, equipmentType); } - private List getAllReportUuids(List nodesModificationInfos) { - return nodesModificationInfos.stream() - .flatMap(nodeInfo -> { - if (nodeInfo.getNodeType() == NodeType.ROOT) { - return Stream.of(nodeInfo.getReportUuid()); - } else { - return Stream.concat( - Optional.ofNullable( - networkModificationTreeService.getComputationReports(nodeInfo.getId())) - .map(Map::values).stream().flatMap(Collection::stream), - Optional.ofNullable( - networkModificationTreeService.getModificationReports(nodeInfo.getId())) - .map(Map::values).stream().flatMap(Collection::stream)); - } - }) - .toList(); - } - private Optional doDeleteStudyIfNotCreationInProgress(UUID studyUuid, String userId) { Optional studyCreationRequestEntity = studyCreationRequestRepository.findById(studyUuid); Optional studyEntity = studyRepository.findById(studyUuid); @@ -408,9 +399,9 @@ private Optional doDeleteStudyIfNotCreationInProgress(UUID stu List nodesModificationInfos; nodesModificationInfos = networkModificationTreeService.getAllNodesModificationInfos(studyUuid); // get all reports related to the study - List reportUuids = getAllReportUuids(nodesModificationInfos); + List reportUuids = rootNetworkService.getAllReportUuids(studyUuid); studyEntity.ifPresent(s -> { - caseUuid.set(studyEntity.get().getCaseUuid()); + caseUuid.set(studyEntity.get().getFirstRootNetwork().getCaseUuid()); networkModificationTreeService.doDeleteTree(studyUuid); studyRepository.deleteById(studyUuid); studyInfosService.deleteByUuid(studyUuid); @@ -448,6 +439,7 @@ public void deleteStudyIfNotCreationInProgress(UUID studyUuid, String userId) { DeleteStudyInfos deleteStudyInfos = deleteStudyInfosOpt.get(); startTime.set(System.nanoTime()); + //TODO: now we have a n-n relation between node and rootNetworks, it's even more important to delete results in a single request CompletableFuture executeInParallel = CompletableFuture.allOf( studyServerExecutionService.runAsync(() -> deleteStudyInfos.getNodesModificationInfos().stream() .map(NodeModificationInfos::getLoadFlowUuid).filter(Objects::nonNull).forEach(loadflowService::deleteLoadFlowResult)), // TODO delete all with one request only @@ -494,26 +486,25 @@ public void deleteEquipmentIndexes(UUID networkUuid) { LOGGER.trace("Indexes deletion for network '{}' : {} seconds", networkUuid, TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime.get())); } - public CreatedStudyBasicInfos insertStudy(UUID studyUuid, String userId, NetworkInfos networkInfos, String caseFormat, - UUID caseUuid, String caseName, UUID loadFlowParametersUuid, + public CreatedStudyBasicInfos insertStudy(UUID studyUuid, String userId, NetworkInfos networkInfos, CaseInfos caseInfos, UUID loadFlowParametersUuid, UUID shortCircuitParametersUuid, DynamicSimulationParametersEntity dynamicSimulationParametersEntity, UUID voltageInitParametersUuid, UUID securityAnalysisParametersUuid, UUID sensitivityAnalysisParametersUuid, Map importParameters, UUID importReportUuid) { Objects.requireNonNull(studyUuid); Objects.requireNonNull(userId); - UUID networkUuid = Objects.requireNonNull(networkInfos.getNetworkUuid()); - String networkId = Objects.requireNonNull(networkInfos.getNetworkId()); - Objects.requireNonNull(caseFormat); - Objects.requireNonNull(caseUuid); + Objects.requireNonNull(networkInfos.getNetworkUuid()); + Objects.requireNonNull(networkInfos.getNetworkId()); + Objects.requireNonNull(caseInfos.getCaseFormat()); + Objects.requireNonNull(caseInfos.getCaseUuid()); Objects.requireNonNull(importParameters); - StudyEntity studyEntity = self.saveStudyThenCreateBasicTree(new StudyEntity(studyUuid, networkUuid, networkId, caseFormat, caseUuid, caseName, - null, null, null, defaultNonEvacuatedEnergyProvider, defaultDynamicSimulationProvider, - loadFlowParametersUuid, shortCircuitParametersUuid, dynamicSimulationParametersEntity, voltageInitParametersUuid, securityAnalysisParametersUuid, - sensitivityAnalysisParametersUuid, null, importParameters, StudyIndexationStatus.INDEXED, new StudyVoltageInitParametersEntity()), - importReportUuid); + StudyEntity studyEntity = self.saveStudyThenCreateBasicTree(studyUuid, networkInfos, + caseInfos, loadFlowParametersUuid, + shortCircuitParametersUuid, dynamicSimulationParametersEntity, + voltageInitParametersUuid, securityAnalysisParametersUuid, sensitivityAnalysisParametersUuid, + importParameters, importReportUuid); - CreatedStudyBasicInfos createdStudyBasicInfos = StudyService.toCreatedStudyBasicInfos(studyEntity); + CreatedStudyBasicInfos createdStudyBasicInfos = toCreatedStudyBasicInfos(studyEntity); studyInfosService.add(createdStudyBasicInfos); notificationService.emitStudiesChanged(studyUuid, userId); @@ -522,9 +513,11 @@ sensitivityAnalysisParametersUuid, null, importParameters, StudyIndexationStatus } public CreatedStudyBasicInfos updateStudyNetwork(StudyEntity studyEntity, String userId, NetworkInfos networkInfos) { - self.updateStudyEntityNetwork(studyEntity, networkInfos); + rootNetworkRepository.findAllByStudyId(studyEntity.getId()).forEach(tp -> { + self.updateStudyEntityNetwork(tp, networkInfos); + }); - CreatedStudyBasicInfos createdStudyBasicInfos = StudyService.toCreatedStudyBasicInfos(studyEntity); + CreatedStudyBasicInfos createdStudyBasicInfos = toCreatedStudyBasicInfos(studyEntity); studyInfosService.add(createdStudyBasicInfos); notificationService.emitStudyNetworkRecreationDone(studyEntity.getId(), userId); @@ -538,12 +531,12 @@ private StudyEntity insertDuplicatedStudy(BasicStudyInfos studyInfos, UUID sourc StudyEntity sourceStudy = studyRepository.findById(sourceStudyUuid).orElseThrow(() -> new StudyException(STUDY_NOT_FOUND)); - List networkVariants = networkStoreService.getNetworkVariants(sourceStudy.getNetworkUuid()); + List networkVariants = networkStoreService.getNetworkVariants(sourceStudy.getFirstRootNetwork().getNetworkUuid()); List targetVariantIds = networkVariants.stream().map(VariantInfos::getId).limit(2).collect(Collectors.toList()); - Network clonedNetwork = networkStoreService.cloneNetwork(sourceStudy.getNetworkUuid(), targetVariantIds); + Network clonedNetwork = networkStoreService.cloneNetwork(sourceStudy.getFirstRootNetwork().getNetworkUuid(), targetVariantIds); UUID clonedNetworkUuid = networkStoreService.getNetworkUuid(clonedNetwork); - UUID clonedCaseUuid = caseService.duplicateCase(sourceStudy.getCaseUuid(), false); + UUID clonedCaseUuid = caseService.duplicateCase(sourceStudy.getFirstRootNetwork().getCaseUuid(), false); Map newImportParameters = Map.copyOf(sourceStudy.getImportParameters()); @@ -578,10 +571,8 @@ private StudyEntity insertDuplicatedStudy(BasicStudyInfos studyInfos, UUID sourc DynamicSimulationParametersInfos dynamicSimulationParameters = sourceStudy.getDynamicSimulationParameters() != null ? DynamicSimulationService.fromEntity(sourceStudy.getDynamicSimulationParameters(), objectMapper) : DynamicSimulationService.getDefaultDynamicSimulationParameters(); - StudyEntity studyEntity = StudyEntity.builder() + StudyEntity newStudyEntity = StudyEntity.builder() .id(studyInfos.getId()) - .networkUuid(clonedNetworkUuid).networkId(sourceStudy.getNetworkId()) - .caseFormat(sourceStudy.getCaseFormat()).caseUuid(clonedCaseUuid).caseName(sourceStudy.getCaseName()) .loadFlowParametersUuid(copiedLoadFlowParametersUuid) .securityAnalysisParametersUuid(copiedSecurityAnalysisParametersUuid) .nonEvacuatedEnergyProvider(sourceStudy.getNonEvacuatedEnergyProvider()) @@ -593,12 +584,18 @@ private StudyEntity insertDuplicatedStudy(BasicStudyInfos studyInfos, UUID sourc .nonEvacuatedEnergyParameters(NonEvacuatedEnergyService.toEntity(nonEvacuatedEnergyParametersInfos)) .importParameters(newImportParameters) .build(); - CreatedStudyBasicInfos createdStudyBasicInfos = StudyService.toCreatedStudyBasicInfos(insertDuplicatedStudy(studyEntity, sourceStudy.getId(), UUID.randomUUID())); + + rootNetworkService.createRootNetwork(newStudyEntity, + new NetworkInfos(clonedNetworkUuid, sourceStudy.getFirstRootNetwork().getNetworkId()), + new CaseInfos(clonedCaseUuid, sourceStudy.getFirstRootNetwork().getCaseName(), sourceStudy.getFirstRootNetwork().getCaseFormat()), + UUID.randomUUID()); + + CreatedStudyBasicInfos createdStudyBasicInfos = toCreatedStudyBasicInfos(insertDuplicatedStudy(newStudyEntity, sourceStudy.getId())); studyInfosService.add(createdStudyBasicInfos); notificationService.emitStudiesChanged(studyInfos.getId(), userId); - return studyEntity; + return newStudyEntity; } private StudyCreationRequestEntity insertStudyCreationRequest(String userId, UUID studyUuid) { @@ -610,7 +607,7 @@ private StudyCreationRequestEntity insertStudyCreationRequest(String userId, UUI public byte[] getVoltageLevelSvg(UUID studyUuid, String voltageLevelId, DiagramParameters diagramParameters, UUID nodeUuid) { UUID networkUuid = networkStoreService.getNetworkUuid(studyUuid); - String variantId = networkModificationTreeService.getVariantId(nodeUuid); + String variantId = networkModificationTreeService.getVariantId(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)); if (networkStoreService.existVariant(networkUuid, variantId)) { return singleLineDiagramService.getVoltageLevelSvg(networkUuid, variantId, voltageLevelId, diagramParameters); } else { @@ -621,7 +618,7 @@ public byte[] getVoltageLevelSvg(UUID studyUuid, String voltageLevelId, DiagramP public String getVoltageLevelSvgAndMetadata(UUID studyUuid, String voltageLevelId, DiagramParameters diagramParameters, UUID nodeUuid) { UUID networkUuid = networkStoreService.getNetworkUuid(studyUuid); - String variantId = networkModificationTreeService.getVariantId(nodeUuid); + String variantId = networkModificationTreeService.getVariantId(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)); if (networkStoreService.existVariant(networkUuid, variantId)) { return singleLineDiagramService.getVoltageLevelSvgAndMetadata(networkUuid, variantId, voltageLevelId, diagramParameters); } else { @@ -637,107 +634,109 @@ private void persistentStoreWithNotificationOnError(UUID caseUuid, UUID studyUui } } - public String getLinesGraphics(UUID networkUuid, UUID nodeUuid, List linesIds) { - String variantId = networkModificationTreeService.getVariantId(nodeUuid); + public String getLinesGraphics(UUID networkUuid, UUID nodeUuid, UUID rootNetworkUuid, List linesIds) { + String variantId = networkModificationTreeService.getVariantId(nodeUuid, rootNetworkUuid); return geoDataService.getLinesGraphics(networkUuid, variantId, linesIds); } - public String getSubstationsGraphics(UUID networkUuid, UUID nodeUuid, List substationsIds) { - String variantId = networkModificationTreeService.getVariantId(nodeUuid); + public String getSubstationsGraphics(UUID networkUuid, UUID nodeUuid, UUID rootNetworkUuid, List substationsIds) { + String variantId = networkModificationTreeService.getVariantId(nodeUuid, rootNetworkUuid); return geoDataService.getSubstationsGraphics(networkUuid, variantId, substationsIds); } public String getSubstationMapData(UUID studyUuid, UUID nodeUuid, String substationId, boolean inUpstreamBuiltParentNode) { - UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, inUpstreamBuiltParentNode); - return networkMapService.getEquipmentMapData(networkStoreService.getNetworkUuid(studyUuid), networkModificationTreeService.getVariantId(nodeUuidToSearchIn), + UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), inUpstreamBuiltParentNode); + return networkMapService.getEquipmentMapData(networkStoreService.getNetworkUuid(studyUuid), networkModificationTreeService.getVariantId(nodeUuidToSearchIn, self.getStudyFirstRootNetworkUuid(studyUuid)), "substations", substationId); } public String getNetworkElementsInfos(UUID studyUuid, UUID nodeUuid, List substationsIds, String infoType, String elementType, boolean inUpstreamBuiltParentNode, List nominalVoltages) { - UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, inUpstreamBuiltParentNode); + UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), inUpstreamBuiltParentNode); StudyEntity studyEntity = studyRepository.findById(studyUuid).orElseThrow(() -> new StudyException(STUDY_NOT_FOUND)); LoadFlowParameters loadFlowParameters = getLoadFlowParameters(studyEntity); - return networkMapService.getElementsInfos(networkStoreService.getNetworkUuid(studyUuid), networkModificationTreeService.getVariantId(nodeUuidToSearchIn), + return networkMapService.getElementsInfos(rootNetworkService.getNetworkUuid(self.getStudyFirstRootNetworkUuid(studyUuid)), networkModificationTreeService.getVariantId(nodeUuidToSearchIn, self.getStudyFirstRootNetworkUuid(studyUuid)), substationsIds, elementType, nominalVoltages, infoType, loadFlowParameters.getDcPowerFactor()); } public String getNetworkElementInfos(UUID studyUuid, UUID nodeUuid, String elementType, InfoTypeParameters infoTypeParameters, String elementId, boolean inUpstreamBuiltParentNode) { - UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, inUpstreamBuiltParentNode); + UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), inUpstreamBuiltParentNode); StudyEntity studyEntity = studyRepository.findById(studyUuid).orElseThrow(() -> new StudyException(STUDY_NOT_FOUND)); LoadFlowParameters loadFlowParameters = getLoadFlowParameters(studyEntity); - return networkMapService.getElementInfos(networkStoreService.getNetworkUuid(studyUuid), networkModificationTreeService.getVariantId(nodeUuidToSearchIn), + return networkMapService.getElementInfos(networkStoreService.getNetworkUuid(studyUuid), networkModificationTreeService.getVariantId(nodeUuidToSearchIn, self.getStudyFirstRootNetworkUuid(studyUuid)), elementType, infoTypeParameters.getInfoType(), infoTypeParameters.getOptionalParameters().getOrDefault(QUERY_PARAM_OPERATION, null), loadFlowParameters.getDcPowerFactor(), elementId); } public String getNetworkCountries(UUID studyUuid, UUID nodeUuid, boolean inUpstreamBuiltParentNode) { - UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, inUpstreamBuiltParentNode); - return networkMapService.getCountries(networkStoreService.getNetworkUuid(studyUuid), networkModificationTreeService.getVariantId(nodeUuidToSearchIn)); + UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), inUpstreamBuiltParentNode); + return networkMapService.getCountries(networkStoreService.getNetworkUuid(studyUuid), networkModificationTreeService.getVariantId(nodeUuidToSearchIn, self.getStudyFirstRootNetworkUuid(studyUuid))); } public String getNetworkNominalVoltages(UUID studyUuid, UUID nodeUuid, boolean inUpstreamBuiltParentNode) { - UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, inUpstreamBuiltParentNode); - return networkMapService.getNominalVoltages(networkStoreService.getNetworkUuid(studyUuid), networkModificationTreeService.getVariantId(nodeUuidToSearchIn)); + UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), inUpstreamBuiltParentNode); + return networkMapService.getNominalVoltages(networkStoreService.getNetworkUuid(studyUuid), networkModificationTreeService.getVariantId(nodeUuidToSearchIn, self.getStudyFirstRootNetworkUuid(studyUuid))); } public String getVoltageLevelEquipments(UUID studyUuid, UUID nodeUuid, List substationsIds, boolean inUpstreamBuiltParentNode, String voltageLevelId) { - UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, inUpstreamBuiltParentNode); + UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), inUpstreamBuiltParentNode); String equipmentPath = "voltage-levels" + StudyConstants.DELIMITER + voltageLevelId + StudyConstants.DELIMITER + "equipments"; - return networkMapService.getEquipmentsMapData(networkStoreService.getNetworkUuid(studyUuid), networkModificationTreeService.getVariantId(nodeUuidToSearchIn), + return networkMapService.getEquipmentsMapData(networkStoreService.getNetworkUuid(studyUuid), networkModificationTreeService.getVariantId(nodeUuidToSearchIn, self.getStudyFirstRootNetworkUuid(studyUuid)), substationsIds, equipmentPath); } public String getHvdcLineShuntCompensators(UUID studyUuid, UUID nodeUuid, boolean inUpstreamBuiltParentNode, String hvdcId) { - UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, inUpstreamBuiltParentNode); + UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), inUpstreamBuiltParentNode); UUID networkUuid = networkStoreService.getNetworkUuid(studyUuid); - String variantId = networkModificationTreeService.getVariantId(nodeUuidToSearchIn); + String variantId = networkModificationTreeService.getVariantId(nodeUuidToSearchIn, self.getStudyFirstRootNetworkUuid(studyUuid)); return networkMapService.getHvdcLineShuntCompensators(networkUuid, variantId, hvdcId); } public String getBranchOrThreeWindingsTransformer(UUID studyUuid, UUID nodeUuid, String equipmentId) { UUID networkUuid = networkStoreService.getNetworkUuid(studyUuid); - String variantId = networkModificationTreeService.getVariantId(nodeUuid); + String variantId = networkModificationTreeService.getVariantId(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)); return networkMapService.getEquipmentMapData(networkUuid, variantId, "branch-or-3wt", equipmentId); } public String getAllMapData(UUID studyUuid, UUID nodeUuid, List substationsIds) { - return networkMapService.getEquipmentsMapData(networkStoreService.getNetworkUuid(studyUuid), networkModificationTreeService.getVariantId(nodeUuid), + return networkMapService.getEquipmentsMapData(networkStoreService.getNetworkUuid(studyUuid), networkModificationTreeService.getVariantId(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)), substationsIds, "all"); } @Transactional - public UUID runLoadFlow(UUID studyUuid, UUID nodeUuid, String userId, Float limitReduction) { + public UUID runLoadFlow(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, String userId, Float limitReduction) { StudyEntity studyEntity = studyRepository.findById(studyUuid).orElseThrow(() -> new StudyException(STUDY_NOT_FOUND)); - Optional prevResultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, LOAD_FLOW); - prevResultUuidOpt.ifPresent(loadflowService::deleteLoadFlowResult); + UUID prevResultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, LOAD_FLOW); + if (prevResultUuid != null) { + loadflowService.deleteLoadFlowResult(prevResultUuid); + } UUID lfParametersUuid = loadflowService.getLoadFlowParametersOrDefaultsUuid(studyEntity); - UUID lfReportUuid = networkModificationTreeService.getComputationReports(nodeUuid).getOrDefault(LOAD_FLOW.name(), UUID.randomUUID()); - networkModificationTreeService.updateComputationReportUuid(nodeUuid, LOAD_FLOW, lfReportUuid); - UUID result = loadflowService.runLoadFlow(studyUuid, nodeUuid, lfParametersUuid, lfReportUuid, userId, limitReduction); + UUID lfReportUuid = networkModificationTreeService.getComputationReports(nodeUuid, rootNetworkUuid).getOrDefault(LOAD_FLOW.name(), UUID.randomUUID()); + networkModificationTreeService.updateComputationReportUuid(nodeUuid, rootNetworkUuid, LOAD_FLOW, lfReportUuid); + UUID result = loadflowService.runLoadFlow(studyUuid, nodeUuid, rootNetworkUuid, lfParametersUuid, lfReportUuid, userId, limitReduction); - updateComputationResultUuid(nodeUuid, result, LOAD_FLOW); + updateComputationResultUuid(nodeUuid, rootNetworkUuid, result, LOAD_FLOW); notificationService.emitStudyChanged(studyUuid, nodeUuid, NotificationService.UPDATE_TYPE_LOADFLOW_STATUS); return result; } public ExportNetworkInfos exportNetwork(UUID studyUuid, UUID nodeUuid, String format, String paramatersJson, String fileName) { UUID networkUuid = networkStoreService.getNetworkUuid(studyUuid); - String variantId = networkModificationTreeService.getVariantId(nodeUuid); + String variantId = networkModificationTreeService.getVariantId(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)); return networkConversionService.exportNetwork(networkUuid, variantId, format, paramatersJson, fileName); } - private void assertComputationNotRunning(UUID nodeUuid) { - loadflowService.assertLoadFlowNotRunning(nodeUuid); - securityAnalysisService.assertSecurityAnalysisNotRunning(nodeUuid); - dynamicSimulationService.assertDynamicSimulationNotRunning(nodeUuid); - sensitivityAnalysisService.assertSensitivityAnalysisNotRunning(nodeUuid); - nonEvacuatedEnergyService.assertNonEvacuatedEnergyNotRunning(nodeUuid); - shortCircuitService.assertShortCircuitAnalysisNotRunning(nodeUuid); - voltageInitService.assertVoltageInitNotRunning(nodeUuid); - stateEstimationService.assertStateEstimationNotRunning(nodeUuid); + private void assertComputationNotRunning(UUID nodeUuid, UUID rootNetworkUuid) { + loadflowService.assertLoadFlowNotRunning(nodeUuid, rootNetworkUuid); + securityAnalysisService.assertSecurityAnalysisNotRunning(nodeUuid, rootNetworkUuid); + dynamicSimulationService.assertDynamicSimulationNotRunning(nodeUuid, rootNetworkUuid); + sensitivityAnalysisService.assertSensitivityAnalysisNotRunning(nodeUuid, rootNetworkUuid); + nonEvacuatedEnergyService.assertNonEvacuatedEnergyNotRunning(nodeUuid, rootNetworkUuid); + shortCircuitService.assertShortCircuitAnalysisNotRunning(nodeUuid, rootNetworkUuid); + voltageInitService.assertVoltageInitNotRunning(nodeUuid, rootNetworkUuid); + stateEstimationService.assertStateEstimationNotRunning(nodeUuid, rootNetworkUuid); } public void assertIsNodeNotReadOnly(UUID nodeUuid) { @@ -757,13 +756,13 @@ public void assertIsNodeExist(UUID studyUuid, UUID nodeUuid) { } public void assertIsStudyExist(UUID studyUuid) { - boolean exists = getStudies().stream() - .anyMatch(study -> studyUuid.equals(study.getId())); + boolean exists = studyRepository.existsById(studyUuid); if (!exists) { throw new StudyException(NODE_NOT_FOUND); } } + @Transactional public void assertCanModifyNode(UUID studyUuid, UUID nodeUuid) { assertIsNodeNotReadOnly(nodeUuid); assertNoBuildNoComputation(studyUuid, nodeUuid); @@ -775,21 +774,23 @@ public void assertIsStudyAndNodeExist(UUID studyUuid, UUID nodeUuid) { } public void assertNoBuildNoComputation(UUID studyUuid, UUID nodeUuid) { - assertComputationNotRunning(nodeUuid); + assertComputationNotRunning(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)); assertNoNodeIsBuilding(studyUuid); } private void assertNoNodeIsBuilding(UUID studyUuid) { - networkModificationTreeService.getAllNodes(studyUuid).stream().forEach(node -> { - if (networkModificationTreeService.getNodeBuildStatus(node.getIdNode()).isBuilding()) { - throw new StudyException(NOT_ALLOWED, "No modification is allowed during a node building."); - } - }); + networkModificationTreeService.getAllNodes(studyUuid).forEach(node -> + rootNetworkNodeInfoRepository.findAllByNodeInfoId(node.getIdNode()).forEach(tpNodeInfo -> { + if (networkModificationTreeService.getNodeBuildStatus(tpNodeInfo).isBuilding()) { + throw new StudyException(NOT_ALLOWED, "No modification is allowed during a node building."); + } + }) + ); } public void assertRootNodeOrBuiltNode(UUID studyUuid, UUID nodeUuid) { if (!(networkModificationTreeService.getStudyRootNodeUuid(studyUuid).equals(nodeUuid) - || networkModificationTreeService.getNodeBuildStatus(nodeUuid).isBuilt())) { + || networkModificationTreeService.getNodeBuildStatus(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)).isBuilt())) { throw new StudyException(NODE_NOT_BUILT); } } @@ -958,31 +959,33 @@ public void setShortCircuitParameters(UUID studyUuid, @Nullable String shortCirc } @Transactional - public UUID runSecurityAnalysis(UUID studyUuid, List contingencyListNames, UUID nodeUuid, String userId) { + public UUID runSecurityAnalysis(UUID studyUuid, List contingencyListNames, UUID nodeUuid, UUID rootNetworkUuid, String userId) { Objects.requireNonNull(studyUuid); Objects.requireNonNull(contingencyListNames); Objects.requireNonNull(nodeUuid); UUID networkUuid = networkStoreService.getNetworkUuid(studyUuid); - String variantId = networkModificationTreeService.getVariantId(nodeUuid); - UUID saReportUuid = networkModificationTreeService.getComputationReports(nodeUuid).getOrDefault(SECURITY_ANALYSIS.name(), UUID.randomUUID()); - networkModificationTreeService.updateComputationReportUuid(nodeUuid, SECURITY_ANALYSIS, saReportUuid); + String variantId = networkModificationTreeService.getVariantId(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)); + UUID saReportUuid = networkModificationTreeService.getComputationReports(nodeUuid, rootNetworkUuid).getOrDefault(SECURITY_ANALYSIS.name(), UUID.randomUUID()); + networkModificationTreeService.updateComputationReportUuid(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), SECURITY_ANALYSIS, saReportUuid); StudyEntity study = studyRepository.findById(studyUuid).orElseThrow(() -> new StudyException(STUDY_NOT_FOUND)); String receiver; try { - receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid)), + receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid, rootNetworkUuid)), StandardCharsets.UTF_8); } catch (JsonProcessingException e) { throw new UncheckedIOException(e); } - Optional prevResultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, SECURITY_ANALYSIS); - prevResultUuidOpt.ifPresent(securityAnalysisService::deleteSaResult); + UUID prevResultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, SECURITY_ANALYSIS); + if (prevResultUuid != null) { + securityAnalysisService.deleteSaResult(prevResultUuid); + } var runSecurityAnalysisParametersInfos = new RunSecurityAnalysisParametersInfos(study.getSecurityAnalysisParametersUuid(), study.getLoadFlowParametersUuid(), contingencyListNames); UUID result = securityAnalysisService.runSecurityAnalysis(networkUuid, variantId, runSecurityAnalysisParametersInfos, new ReportInfos(saReportUuid, nodeUuid), receiver, userId); - updateComputationResultUuid(nodeUuid, result, SECURITY_ANALYSIS); + updateComputationResultUuid(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), result, SECURITY_ANALYSIS); notificationService.emitStudyChanged(studyUuid, nodeUuid, NotificationService.UPDATE_TYPE_SECURITY_ANALYSIS_STATUS); return result; } @@ -993,21 +996,21 @@ public Integer getContingencyCount(UUID studyUuid, List contingencyListN Objects.requireNonNull(nodeUuid); UUID networkuuid = networkStoreService.getNetworkUuid(studyUuid); - String variantId = networkModificationTreeService.getVariantId(nodeUuid); + String variantId = networkModificationTreeService.getVariantId(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)); return actionsService.getContingencyCount(networkuuid, variantId, contingencyListNames); } public List getLimitViolations(@NonNull UUID studyUuid, @NonNull UUID nodeUuid, String filters, String globalFilters, Sort sort) { UUID networkuuid = networkStoreService.getNetworkUuid(studyUuid); - String variantId = networkModificationTreeService.getVariantId(nodeUuid); - return loadflowService.getLimitViolations(nodeUuid, filters, globalFilters, sort, networkuuid, variantId); + String variantId = networkModificationTreeService.getVariantId(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)); + return loadflowService.getLimitViolations(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), filters, globalFilters, sort, networkuuid, variantId); } public byte[] getSubstationSvg(UUID studyUuid, String substationId, DiagramParameters diagramParameters, String substationLayout, UUID nodeUuid) { UUID networkUuid = networkStoreService.getNetworkUuid(studyUuid); - String variantId = networkModificationTreeService.getVariantId(nodeUuid); + String variantId = networkModificationTreeService.getVariantId(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)); if (networkStoreService.existVariant(networkUuid, variantId)) { return singleLineDiagramService.getSubstationSvg(networkUuid, variantId, substationId, diagramParameters, substationLayout); } else { @@ -1018,7 +1021,7 @@ public byte[] getSubstationSvg(UUID studyUuid, String substationId, DiagramParam public String getSubstationSvgAndMetadata(UUID studyUuid, String substationId, DiagramParameters diagramParameters, String substationLayout, UUID nodeUuid) { UUID networkUuid = networkStoreService.getNetworkUuid(studyUuid); - String variantId = networkModificationTreeService.getVariantId(nodeUuid); + String variantId = networkModificationTreeService.getVariantId(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)); if (networkStoreService.existVariant(networkUuid, variantId)) { return singleLineDiagramService.getSubstationSvgAndMetadata(networkUuid, variantId, substationId, diagramParameters, substationLayout); } else { @@ -1028,7 +1031,7 @@ public String getSubstationSvgAndMetadata(UUID studyUuid, String substationId, D public String getNetworkAreaDiagram(UUID studyUuid, UUID nodeUuid, List voltageLevelsIds, int depth, boolean withGeoData) { UUID networkUuid = networkStoreService.getNetworkUuid(studyUuid); - String variantId = networkModificationTreeService.getVariantId(nodeUuid); + String variantId = networkModificationTreeService.getVariantId(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)); if (networkStoreService.existVariant(networkUuid, variantId)) { return singleLineDiagramService.getNetworkAreaDiagram(networkUuid, variantId, voltageLevelsIds, depth, withGeoData); } else { @@ -1061,15 +1064,13 @@ public void invalidateVoltageInitStatusOnAllNodes(UUID studyUuid) { } @Transactional - public StudyEntity updateStudyEntityNetwork(StudyEntity studyEntity, NetworkInfos networkInfos) { + public void updateStudyEntityNetwork(RootNetworkEntity rootNetworkEntity, NetworkInfos networkInfos) { if (networkInfos != null) { - studyEntity.setNetworkId(networkInfos.getNetworkId()); - studyEntity.setNetworkUuid(networkInfos.getNetworkUuid()); + rootNetworkEntity.setNetworkId(networkInfos.getNetworkId()); + rootNetworkEntity.setNetworkUuid(networkInfos.getNetworkUuid()); - studyRepository.save(studyEntity); + rootNetworkRepository.save(rootNetworkEntity); } - - return studyEntity; } private StudyEntity updateStudyIndexationStatus(StudyEntity studyEntity, StudyIndexationStatus indexationStatus) { @@ -1083,36 +1084,57 @@ public StudyEntity updateStudyIndexationStatus(UUID studyUuid, StudyIndexationSt } @Transactional - public StudyEntity saveStudyThenCreateBasicTree(StudyEntity studyEntity, UUID importReportUuid) { + public StudyEntity saveStudyThenCreateBasicTree(UUID studyUuid, NetworkInfos networkInfos, + CaseInfos caseInfos, UUID loadFlowParametersUuid, + UUID shortCircuitParametersUuid, DynamicSimulationParametersEntity dynamicSimulationParametersEntity, + UUID voltageInitParametersUuid, UUID securityAnalysisParametersUuid, UUID sensitivityAnalysisParametersUuid, + Map importParameters, UUID importReportUuid) { + + StudyEntity studyEntity = StudyEntity.builder() + .id(studyUuid) + .nonEvacuatedEnergyProvider(defaultNonEvacuatedEnergyProvider) + .dynamicSimulationProvider(defaultDynamicSimulationProvider) + .loadFlowParametersUuid(loadFlowParametersUuid) + .shortCircuitParametersUuid(shortCircuitParametersUuid) + .dynamicSimulationParameters(dynamicSimulationParametersEntity) + .voltageInitParametersUuid(voltageInitParametersUuid) + .securityAnalysisParametersUuid(securityAnalysisParametersUuid) + .sensitivityAnalysisParametersUuid(sensitivityAnalysisParametersUuid) + .importParameters(importParameters) + .indexationStatus(StudyIndexationStatus.INDEXED) + .voltageInitParameters(new StudyVoltageInitParametersEntity()) + .build(); + var study = studyRepository.save(studyEntity); + rootNetworkService.createRootNetwork(studyEntity, networkInfos, caseInfos, importReportUuid); + networkModificationTreeService.createBasicTree(study); - networkModificationTreeService.createBasicTree(study, importReportUuid); return study; } - private StudyEntity insertDuplicatedStudy(StudyEntity studyEntity, UUID sourceStudyUuid, UUID reportUuid) { + private StudyEntity insertDuplicatedStudy(StudyEntity studyEntity, UUID sourceStudyUuid) { var study = studyRepository.save(studyEntity); - networkModificationTreeService.createRoot(study, reportUuid); + networkModificationTreeService.createRoot(study); AbstractNode rootNode = networkModificationTreeService.getStudyTree(sourceStudyUuid); networkModificationTreeService.cloneStudyTree(rootNode, null, studyEntity); return study; } - void updateComputationResultUuid(UUID nodeUuid, UUID computationResultUuid, ComputationType computationType) { - networkModificationTreeService.updateComputationResultUuid(nodeUuid, computationResultUuid, computationType); + void updateComputationResultUuid(UUID nodeUuid, UUID rootNetworkUuid, UUID computationResultUuid, ComputationType computationType) { + networkModificationTreeService.updateComputationResultUuid(nodeUuid, rootNetworkUuid, computationResultUuid, computationType); } public List getResultEnumValues(UUID studyUuid, UUID nodeUuid, ComputationType computationType, String enumName) { Objects.requireNonNull(studyUuid); Objects.requireNonNull(nodeUuid); Objects.requireNonNull(enumName); - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, computationType); - if (resultUuidOpt.isPresent()) { + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), computationType); + if (resultUuid != null) { return switch (computationType) { - case LOAD_FLOW -> loadflowService.getEnumValues(enumName, resultUuidOpt.get()); - case SECURITY_ANALYSIS -> securityAnalysisService.getEnumValues(enumName, resultUuidOpt.get()); - case SHORT_CIRCUIT, SHORT_CIRCUIT_ONE_BUS -> shortCircuitService.getEnumValues(enumName, resultUuidOpt.get()); + case LOAD_FLOW -> loadflowService.getEnumValues(enumName, resultUuid); + case SECURITY_ANALYSIS -> securityAnalysisService.getEnumValues(enumName, resultUuid); + case SHORT_CIRCUIT, SHORT_CIRCUIT_ONE_BUS -> shortCircuitService.getEnumValues(enumName, resultUuid); default -> throw new StudyException(NOT_ALLOWED); }; } else { @@ -1209,12 +1231,12 @@ public void createNetworkModification(UUID studyUuid, String createModificationA List childrenUuids = networkModificationTreeService.getChildren(nodeUuid); notificationService.emitStartModificationEquipmentNotification(studyUuid, nodeUuid, childrenUuids, NotificationService.MODIFICATIONS_CREATING_IN_PROGRESS); try { - NodeModificationInfos nodeInfos = networkModificationTreeService.getNodeModificationInfos(nodeUuid); - UUID groupUuid = nodeInfos.getModificationGroupUuid(); - String variantId = nodeInfos.getVariantId(); - UUID reportUuid = nodeInfos.getReportUuid(); + RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = rootNetworkService.getRootNetworkNodeInfo(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)).orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND)); + UUID groupUuid = networkModificationTreeService.getModificationGroupUuid(nodeUuid); + String variantId = rootNetworkNodeInfoEntity.getVariantId(); + UUID reportUuid = rootNetworkNodeInfoEntity.getModificationReports().get(nodeUuid); - Optional networkModificationResult = networkModificationService.createModification(studyUuid, createModificationAttributes, groupUuid, variantId, reportUuid, nodeInfos.getId()); + Optional networkModificationResult = networkModificationService.createModification(studyUuid, createModificationAttributes, groupUuid, variantId, reportUuid, nodeUuid); updateNode(studyUuid, nodeUuid, networkModificationResult); } finally { notificationService.emitEndModificationEquipmentNotification(studyUuid, nodeUuid, childrenUuids); @@ -1227,7 +1249,7 @@ public void updateNetworkModification(UUID studyUuid, String updateModificationA notificationService.emitStartModificationEquipmentNotification(studyUuid, nodeUuid, childrenUuids, NotificationService.MODIFICATIONS_UPDATING_IN_PROGRESS); try { networkModificationService.updateModification(updateModificationAttributes, modificationUuid); - updateStatuses(studyUuid, nodeUuid, false); + updateStatuses(studyUuid, nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), false); } finally { notificationService.emitEndModificationEquipmentNotification(studyUuid, nodeUuid, childrenUuids); } @@ -1237,18 +1259,18 @@ public void updateNetworkModification(UUID studyUuid, String updateModificationA public List getVoltageLevelBusesOrBusbarSections(UUID studyUuid, UUID nodeUuid, String voltageLevelId, String busPath) { UUID networkUuid = networkStoreService.getNetworkUuid(studyUuid); - String variantId = networkModificationTreeService.getVariantId(nodeUuid); + String variantId = networkModificationTreeService.getVariantId(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)); return networkMapService.getVoltageLevelBusesOrBusbarSections(networkUuid, variantId, voltageLevelId, busPath); } public List getVoltageLevelBuses(UUID studyUuid, UUID nodeUuid, String voltageLevelId, boolean inUpstreamBuiltParentNode) { - UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, inUpstreamBuiltParentNode); + UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), inUpstreamBuiltParentNode); return getVoltageLevelBusesOrBusbarSections(studyUuid, nodeUuidToSearchIn, voltageLevelId, "configured-buses"); } public List getVoltageLevelBusbarSections(UUID studyUuid, UUID nodeUuid, String voltageLevelId, boolean inUpstreamBuiltParentNode) { - UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, inUpstreamBuiltParentNode); + UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), inUpstreamBuiltParentNode); return getVoltageLevelBusesOrBusbarSections(studyUuid, nodeUuidToSearchIn, voltageLevelId, "busbar-sections"); } @@ -1259,14 +1281,14 @@ public UUID getStudyUuidFromNodeUuid(UUID nodeUuid) { public void buildNode(@NonNull UUID studyUuid, @NonNull UUID nodeUuid, @NonNull String userId) { assertCanBuildNode(studyUuid, userId); - BuildInfos buildInfos = networkModificationTreeService.getBuildInfos(nodeUuid); + BuildInfos buildInfos = networkModificationTreeService.getBuildInfos(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)); Map nodeUuidToReportUuid = buildInfos.getReportsInfos().stream().collect(Collectors.toMap(ReportInfos::nodeUuid, ReportInfos::reportUuid)); - networkModificationTreeService.setModificationReports(nodeUuid, nodeUuidToReportUuid); - networkModificationTreeService.updateNodeBuildStatus(nodeUuid, NodeBuildStatus.from(BuildStatus.BUILDING)); + networkModificationTreeService.setModificationReports(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), nodeUuidToReportUuid); + networkModificationTreeService.updateNodeBuildStatus(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), NodeBuildStatus.from(BuildStatus.BUILDING)); try { - networkModificationService.buildNode(studyUuid, nodeUuid, buildInfos); + networkModificationService.buildNode(studyUuid, nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), buildInfos); } catch (Exception e) { - networkModificationTreeService.updateNodeBuildStatus(nodeUuid, NodeBuildStatus.from(BuildStatus.NOT_BUILT)); + networkModificationTreeService.updateNodeBuildStatus(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), NodeBuildStatus.from(BuildStatus.NOT_BUILT)); throw new StudyException(NODE_BUILD_ERROR, e.getMessage()); } } @@ -1274,20 +1296,21 @@ public void buildNode(@NonNull UUID studyUuid, @NonNull UUID nodeUuid, @NonNull private void assertCanBuildNode(@NonNull UUID studyUuid, @NonNull String userId) { // check restrictions on node builds number userAdminService.getUserMaxAllowedBuilds(userId).ifPresent(maxBuilds -> { - long nbBuiltNodes = networkModificationTreeService.countBuiltNodes(studyUuid); + long nbBuiltNodes = networkModificationTreeService.countBuiltNodes(studyUuid, self.getStudyFirstRootNetworkUuid(studyUuid)); if (nbBuiltNodes >= maxBuilds) { throw new StudyException(MAX_NODE_BUILDS_EXCEEDED, "max allowed built nodes : " + maxBuilds); } }); } + @Transactional public void unbuildNode(@NonNull UUID studyUuid, @NonNull UUID nodeUuid) { - invalidateBuild(studyUuid, nodeUuid, false, true, true); + invalidateBuild(studyUuid, nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), false, true, true); emitAllComputationStatusChanged(studyUuid, nodeUuid); } - public void stopBuild(@NonNull UUID nodeUuid) { - networkModificationService.stopBuild(nodeUuid); + public void stopBuild(@NonNull UUID nodeUuid, UUID rootNetworkUuid) { + networkModificationService.stopBuild(nodeUuid, rootNetworkUuid); } @Transactional @@ -1296,7 +1319,7 @@ public void duplicateStudyNode(UUID sourceStudyUuid, UUID targetStudyUuid, UUID checkStudyContainsNode(targetStudyUuid, referenceNodeUuid); UUID duplicatedNodeUuid = networkModificationTreeService.duplicateStudyNode(nodeToCopyUuid, referenceNodeUuid, insertMode); boolean invalidateBuild = networkModificationTreeService.hasModifications(nodeToCopyUuid, false); - updateStatuses(targetStudyUuid, duplicatedNodeUuid, true, invalidateBuild, true); + updateStatuses(targetStudyUuid, duplicatedNodeUuid, self.getStudyFirstRootNetworkUuid(targetStudyUuid), true, invalidateBuild, true); notificationService.emitElementUpdated(targetStudyUuid, userId); } @@ -1316,10 +1339,10 @@ public void moveStudyNode(UUID studyUuid, UUID nodeToMoveUuid, UUID referenceNod //Invalidating moved node or new children if necessary if (shouldInvalidateChildren) { - updateStatuses(studyUuid, nodeToMoveUuid, false, true, true); - oldChildren.forEach(child -> updateStatuses(studyUuid, child.getIdNode(), false, true, true)); + updateStatuses(studyUuid, nodeToMoveUuid, self.getStudyFirstRootNetworkUuid(studyUuid), false, true, true); + oldChildren.forEach(child -> updateStatuses(studyUuid, child.getIdNode(), self.getStudyFirstRootNetworkUuid(studyUuid), false, true, true)); } else { - invalidateBuild(studyUuid, nodeToMoveUuid, false, true, true); + invalidateBuild(studyUuid, nodeToMoveUuid, self.getStudyFirstRootNetworkUuid(studyUuid), false, true, true); } notificationService.emitElementUpdated(studyUuid, userId); } @@ -1345,27 +1368,27 @@ public void moveStudySubtree(UUID studyUuid, UUID parentNodeToMoveUuid, UUID ref } networkModificationTreeService.moveStudySubtree(parentNodeToMoveUuid, referenceNodeUuid); - if (networkModificationTreeService.getNodeBuildStatus(parentNodeToMoveUuid).isBuilt()) { - updateStatuses(studyUuid, parentNodeToMoveUuid, false, true, true); + if (networkModificationTreeService.getNodeBuildStatus(parentNodeToMoveUuid, self.getStudyFirstRootNetworkUuid(studyUuid)).isBuilt()) { + updateStatuses(studyUuid, parentNodeToMoveUuid, self.getStudyFirstRootNetworkUuid(studyUuid), false, true, true); } allChildren.stream() - .filter(childUuid -> networkModificationTreeService.getNodeBuildStatus(childUuid).isBuilt()) - .forEach(childUuid -> updateStatuses(studyUuid, childUuid, false, true, true)); + .filter(childUuid -> networkModificationTreeService.getNodeBuildStatus(childUuid, self.getStudyFirstRootNetworkUuid(studyUuid)).isBuilt()) + .forEach(childUuid -> updateStatuses(studyUuid, childUuid, self.getStudyFirstRootNetworkUuid(studyUuid), false, true, true)); notificationService.emitSubtreeMoved(studyUuid, parentNodeToMoveUuid, referenceNodeUuid); notificationService.emitElementUpdated(studyUuid, userId); } - public void invalidateBuild(UUID studyUuid, UUID nodeUuid, boolean invalidateOnlyChildrenBuildStatus, boolean invalidateOnlyTargetNode, boolean deleteVoltageInitResults) { + public void invalidateBuild(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, boolean invalidateOnlyChildrenBuildStatus, boolean invalidateOnlyTargetNode, boolean deleteVoltageInitResults) { AtomicReference startTime = new AtomicReference<>(null); startTime.set(System.nanoTime()); InvalidateNodeInfos invalidateNodeInfos = new InvalidateNodeInfos(); - invalidateNodeInfos.setNetworkUuid(networkStoreService.doGetNetworkUuid(studyUuid)); + invalidateNodeInfos.setNetworkUuid(rootNetworkService.getNetworkUuid(rootNetworkUuid)); // we might want to invalidate target node without impacting other nodes (when moving an empty node for example) if (invalidateOnlyTargetNode) { - networkModificationTreeService.invalidateBuildOfNodeOnly(nodeUuid, invalidateOnlyChildrenBuildStatus, invalidateNodeInfos, deleteVoltageInitResults); + networkModificationTreeService.invalidateBuildOfNodeOnly(nodeUuid, rootNetworkUuid, invalidateOnlyChildrenBuildStatus, invalidateNodeInfos, deleteVoltageInitResults); } else { - networkModificationTreeService.invalidateBuild(nodeUuid, invalidateOnlyChildrenBuildStatus, invalidateNodeInfos, deleteVoltageInitResults); + networkModificationTreeService.invalidateBuild(nodeUuid, rootNetworkUuid, invalidateOnlyChildrenBuildStatus, invalidateNodeInfos, deleteVoltageInitResults); } CompletableFuture executeInParallel = CompletableFuture.allOf( @@ -1396,17 +1419,17 @@ public void invalidateBuild(UUID studyUuid, UUID nodeUuid, boolean invalidateOnl } } - private void updateStatuses(UUID studyUuid, UUID nodeUuid) { - updateStatuses(studyUuid, nodeUuid, true); + private void updateStatuses(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid) { + updateStatuses(studyUuid, nodeUuid, rootNetworkUuid, true); } - private void updateStatuses(UUID studyUuid, UUID nodeUuid, boolean invalidateOnlyChildrenBuildStatus) { - updateStatuses(studyUuid, nodeUuid, invalidateOnlyChildrenBuildStatus, true, true); + private void updateStatuses(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, boolean invalidateOnlyChildrenBuildStatus) { + updateStatuses(studyUuid, nodeUuid, rootNetworkUuid, invalidateOnlyChildrenBuildStatus, true, true); } - private void updateStatuses(UUID studyUuid, UUID nodeUuid, boolean invalidateOnlyChildrenBuildStatus, boolean invalidateBuild, boolean deleteVoltageInitResults) { + private void updateStatuses(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, boolean invalidateOnlyChildrenBuildStatus, boolean invalidateBuild, boolean deleteVoltageInitResults) { if (invalidateBuild) { - invalidateBuild(studyUuid, nodeUuid, invalidateOnlyChildrenBuildStatus, false, deleteVoltageInitResults); + invalidateBuild(studyUuid, nodeUuid, rootNetworkUuid, invalidateOnlyChildrenBuildStatus, false, deleteVoltageInitResults); } emitAllComputationStatusChanged(studyUuid, nodeUuid); } @@ -1422,7 +1445,7 @@ public void deleteNetworkModifications(UUID studyUuid, UUID nodeUuid, List UUID groupId = networkModificationTreeService.getModificationGroupUuid(nodeUuid); networkModificationService.deleteModifications(groupId, modificationsUuids); - updateStatuses(studyUuid, nodeUuid, false, false, false); + updateStatuses(studyUuid, nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), false, false, false); } finally { notificationService.emitEndDeletionEquipmentNotification(studyUuid, nodeUuid, childrenUuids); } @@ -1439,7 +1462,7 @@ public void stashNetworkModifications(UUID studyUuid, UUID nodeUuid, List } UUID groupId = networkModificationTreeService.getModificationGroupUuid(nodeUuid); networkModificationService.stashModifications(groupId, modificationsUuids); - updateStatuses(studyUuid, nodeUuid, false); + updateStatuses(studyUuid, nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), false); } finally { notificationService.emitEndModificationEquipmentNotification(studyUuid, nodeUuid, childrenUuids); } @@ -1456,7 +1479,7 @@ public void updateNetworkModificationsActivation(UUID studyUuid, UUID nodeUuid, } UUID groupId = networkModificationTreeService.getModificationGroupUuid(nodeUuid); networkModificationService.updateModificationsActivation(groupId, modificationsUuids, activated); - updateStatuses(studyUuid, nodeUuid, false); + updateStatuses(studyUuid, nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), false); } finally { notificationService.emitEndModificationEquipmentNotification(studyUuid, nodeUuid, childrenUuids); } @@ -1473,7 +1496,7 @@ public void restoreNetworkModifications(UUID studyUuid, UUID nodeUuid, List nodeIds, boolean deleteChildr } if (invalidateChildrenBuild) { - childrenNodes.forEach(nodeEntity -> updateStatuses(studyUuid, nodeEntity.getIdNode(), false, true, true)); + childrenNodes.forEach(nodeEntity -> updateStatuses(studyUuid, nodeEntity.getIdNode(), self.getStudyFirstRootNetworkUuid(studyUuid), false, true, true)); } } @@ -1539,7 +1562,7 @@ public void stashNode(UUID studyUuid, UUID nodeId, boolean stashChildren, String AtomicReference startTime = new AtomicReference<>(null); startTime.set(System.nanoTime()); boolean invalidateChildrenBuild = stashChildren || networkModificationTreeService.hasModifications(nodeId, false); - invalidateBuild(studyUuid, nodeId, false, !invalidateChildrenBuild, true); + invalidateBuild(studyUuid, nodeId, self.getStudyFirstRootNetworkUuid(studyUuid), false, !invalidateChildrenBuild, true); networkModificationTreeService.doStashNode(studyUuid, nodeId, stashChildren); if (startTime.get() != null) { @@ -1566,14 +1589,14 @@ private void reindexStudy(StudyEntity study) { // Reset indexation status updateStudyIndexationStatus(study, StudyIndexationStatus.INDEXING_ONGOING); try { - networkConversionService.reindexStudyNetworkEquipments(study.getNetworkUuid()); + networkConversionService.reindexStudyNetworkEquipments(study.getFirstRootNetwork().getNetworkUuid()); updateStudyIndexationStatus(study, StudyIndexationStatus.INDEXED); } catch (Exception e) { // Allow to retry indexation updateStudyIndexationStatus(study, StudyIndexationStatus.NOT_INDEXED); throw e; } - invalidateBuild(study.getId(), networkModificationTreeService.getStudyRootNodeUuid(study.getId()), false, false, true); + invalidateBuild(study.getId(), networkModificationTreeService.getStudyRootNodeUuid(study.getId()), self.getStudyFirstRootNetworkUuid(study.getId()), false, false, true); LOGGER.info("Study with id = '{}' has been reindexed", study.getId()); } @@ -1586,7 +1609,7 @@ public void reindexStudy(UUID studyUuid) { public StudyIndexationStatus getStudyIndexationStatus(UUID studyUuid) { StudyEntity study = studyRepository.findById(studyUuid).orElseThrow(() -> new StudyException(STUDY_NOT_FOUND)); if (study.getIndexationStatus() == StudyIndexationStatus.INDEXED - && !networkConversionService.checkStudyIndexationStatus(study.getNetworkUuid())) { + && !networkConversionService.checkStudyIndexationStatus(study.getFirstRootNetwork().getNetworkUuid())) { updateStudyIndexationStatus(study, StudyIndexationStatus.NOT_INDEXED); } return study.getIndexationStatus(); @@ -1615,18 +1638,19 @@ public void moveModifications(UUID studyUuid, UUID targetNodeUuid, UUID originNo try { checkStudyContainsNode(studyUuid, targetNodeUuid); UUID originGroupUuid = networkModificationTreeService.getModificationGroupUuid(originNodeUuid); - NodeModificationInfos nodeInfos = networkModificationTreeService.getNodeModificationInfos(targetNodeUuid); + NetworkModificationNodeInfoEntity networkModificationNodeInfoEntity = networkModificationTreeService.getNetworkModificationNodeInfoEntity(targetNodeUuid); + RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = rootNetworkService.getRootNetworkNodeInfo(targetNodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)).orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND)); UUID networkUuid = networkStoreService.getNetworkUuid(studyUuid); - Optional networkModificationResult = networkModificationService.moveModifications(originGroupUuid, modificationUuidList, beforeUuid, networkUuid, nodeInfos, buildTargetNode); + Optional networkModificationResult = networkModificationService.moveModifications(originGroupUuid, modificationUuidList, beforeUuid, networkUuid, networkModificationNodeInfoEntity, rootNetworkNodeInfoEntity, buildTargetNode); if (!targetNodeBelongsToSourceNodeSubTree) { // invalidate the whole subtree except maybe the target node itself (depends if we have built this node during the move) - networkModificationResult.ifPresent(modificationResult -> emitNetworkModificationImpacts(studyUuid, targetNodeUuid, modificationResult)); - updateStatuses(studyUuid, targetNodeUuid, buildTargetNode, true, true); + networkModificationResult.ifPresent(modificationResult -> emitNetworkModificationImpacts(studyUuid, targetNodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), modificationResult)); + updateStatuses(studyUuid, targetNodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), buildTargetNode, true, true); } if (moveBetweenNodes) { // invalidate the whole subtree including the source node - networkModificationResult.ifPresent(modificationResult -> emitNetworkModificationImpacts(studyUuid, originNodeUuid, modificationResult)); - updateStatuses(studyUuid, originNodeUuid, false, true, true); + networkModificationResult.ifPresent(modificationResult -> emitNetworkModificationImpacts(studyUuid, originNodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), modificationResult)); + updateStatuses(studyUuid, originNodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), false, true, true); } } finally { notificationService.emitEndModificationEquipmentNotification(studyUuid, targetNodeUuid, childrenUuids); @@ -1643,12 +1667,13 @@ public void createModifications(UUID studyUuid, UUID nodeUuid, List modifi notificationService.emitStartModificationEquipmentNotification(studyUuid, nodeUuid, childrenUuids, NotificationService.MODIFICATIONS_UPDATING_IN_PROGRESS); try { checkStudyContainsNode(studyUuid, nodeUuid); - NodeModificationInfos nodeInfos = networkModificationTreeService.getNodeModificationInfos(nodeUuid); + NetworkModificationNodeInfoEntity networkModificationNodeInfoEntity = networkModificationTreeService.getNetworkModificationNodeInfoEntity(nodeUuid); + RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = rootNetworkService.getRootNetworkNodeInfo(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)).orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND)); UUID networkUuid = networkStoreService.getNetworkUuid(studyUuid); - Optional networkModificationResult = networkModificationService.createModifications(modificationUuidList, networkUuid, nodeInfos, action); + Optional networkModificationResult = networkModificationService.createModifications(modificationUuidList, networkUuid, networkModificationNodeInfoEntity, rootNetworkNodeInfoEntity, action); // invalidate the whole subtree except the target node (we have built this node during the duplication) - networkModificationResult.ifPresent(modificationResult -> emitNetworkModificationImpacts(studyUuid, nodeUuid, modificationResult)); - updateStatuses(studyUuid, nodeUuid, true, true, true); + networkModificationResult.ifPresent(modificationResult -> emitNetworkModificationImpacts(studyUuid, nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), modificationResult)); + updateStatuses(studyUuid, nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), true, true, true); } finally { notificationService.emitEndModificationEquipmentNotification(studyUuid, nodeUuid, childrenUuids); } @@ -1667,55 +1692,55 @@ public List getReportLogs(String reportId, String messageFilter, Set< } @Transactional(readOnly = true) - public List getParentNodesReportLogs(UUID nodeUuid, String messageFilter, Set severityLevels) { + public List getParentNodesReportLogs(UUID nodeUuid, UUID rootNetworkUuid, String messageFilter, Set severityLevels) { List nodeIds = nodesTree(nodeUuid); List reportLogs = new ArrayList<>(); - Map modificationReportsMap = networkModificationTreeService.getModificationReports(nodeUuid); + Map modificationReportsMap = networkModificationTreeService.getModificationReports(nodeUuid, rootNetworkUuid); for (UUID nodeId : nodeIds) { - UUID reportId = modificationReportsMap.getOrDefault(nodeId, networkModificationTreeService.getReportUuid(nodeId)); + UUID reportId = modificationReportsMap.getOrDefault(nodeId, networkModificationTreeService.getReportUuid(nodeId, rootNetworkUuid)); reportLogs.addAll(reportService.getReportLogs(reportId, messageFilter, severityLevels)); } return reportLogs; } @Transactional(readOnly = true) - public List getParentNodesReport(UUID nodeUuid, boolean nodeOnlyReport, ReportType reportType, Set severityLevels) { + public List getParentNodesReport(UUID nodeUuid, UUID rootNetworkUuid, boolean nodeOnlyReport, ReportType reportType, Set severityLevels) { AbstractNode nodeInfos = networkModificationTreeService.getNode(nodeUuid); - + if (isNonRootNodeWithComputationReportType(nodeInfos, reportType)) { - UUID reportUuid = getReportUuidForNode(nodeUuid, reportType); + UUID reportUuid = getReportUuidForNode(nodeUuid, rootNetworkUuid, reportType); return reportUuid != null ? List.of(reportService.getReport(reportUuid, nodeUuid.toString(), severityLevels)) : Collections.emptyList(); } else if (nodeOnlyReport) { - return getNodeOnlyReport(nodeUuid, severityLevels); + return getNodeOnlyReport(nodeUuid, rootNetworkUuid, severityLevels); } else { - return getAllModificationReports(nodeUuid, severityLevels); + return getAllModificationReports(nodeUuid, rootNetworkUuid, severityLevels); } } - + private boolean isNonRootNodeWithComputationReportType(AbstractNode nodeInfos, ReportType reportType) { return nodeInfos.getType() != NodeType.ROOT && reportType != ReportType.NETWORK_MODIFICATION; } - - private UUID getReportUuidForNode(UUID nodeUuid, ReportType reportType) { - return networkModificationTreeService.getComputationReports(nodeUuid).get(reportType.name()); + + private UUID getReportUuidForNode(UUID nodeUuid, UUID rootNetworkUuid, ReportType reportType) { + return networkModificationTreeService.getComputationReports(nodeUuid, rootNetworkUuid).get(reportType.name()); } - - private List getNodeOnlyReport(UUID nodeUuid, Set severityLevels) { - UUID reportUuid = networkModificationTreeService.getReportUuid(nodeUuid); + + private List getNodeOnlyReport(UUID nodeUuid, UUID rootNetworkUuid, Set severityLevels) { + UUID reportUuid = networkModificationTreeService.getReportUuid(nodeUuid, rootNetworkUuid); return List.of(reportService.getReport(reportUuid, nodeUuid.toString(), severityLevels)); } - - private List getAllModificationReports(UUID nodeUuid, Set severityLevels) { + + private List getAllModificationReports(UUID nodeUuid, UUID rootNetworkUuid, Set severityLevels) { List nodeIds = nodesTree(nodeUuid); List modificationReports = new ArrayList<>(); - Map modificationReportsMap = networkModificationTreeService.getModificationReports(nodeUuid); + Map modificationReportsMap = networkModificationTreeService.getModificationReports(nodeUuid, rootNetworkUuid); for (UUID nodeId : nodeIds) { - UUID reportId = modificationReportsMap.getOrDefault(nodeId, networkModificationTreeService.getReportUuid(nodeId)); + UUID reportId = modificationReportsMap.getOrDefault(nodeId, networkModificationTreeService.getReportUuid(nodeId, rootNetworkUuid)); modificationReports.add(reportService.getReport(reportId, nodeId.toString(), severityLevels)); } - + return modificationReports; } @@ -1723,7 +1748,7 @@ private List nodesTree(UUID nodeUuid) { List nodeIds = new ArrayList<>(); nodeIds.add(nodeUuid); Optional parentUuid = networkModificationTreeService.getParentNodeUuid(nodeUuid); - + while (parentUuid.isPresent()) { nodeIds.add(parentUuid.get()); parentUuid = networkModificationTreeService.getParentNodeUuid(parentUuid.get()); @@ -1734,13 +1759,13 @@ private List nodesTree(UUID nodeUuid) { } private void updateNode(UUID studyUuid, UUID nodeUuid, Optional networkModificationResult) { - networkModificationResult.ifPresent(modificationResult -> emitNetworkModificationImpacts(studyUuid, nodeUuid, modificationResult)); - updateStatuses(studyUuid, nodeUuid); + networkModificationResult.ifPresent(modificationResult -> emitNetworkModificationImpacts(studyUuid, nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), modificationResult)); + updateStatuses(studyUuid, nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)); } - private void emitNetworkModificationImpacts(UUID studyUuid, UUID nodeUuid, NetworkModificationResult networkModificationResult) { + private void emitNetworkModificationImpacts(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, NetworkModificationResult networkModificationResult) { //TODO move this / rename parent method when refactoring notifications - networkModificationTreeService.updateNodeBuildStatus(nodeUuid, + networkModificationTreeService.updateNodeBuildStatus(nodeUuid, rootNetworkUuid, NodeBuildStatus.from(networkModificationResult.getLastGroupApplicationStatus(), networkModificationResult.getApplicationStatus())); Set deletionsInfos = @@ -1776,47 +1801,53 @@ public UUID runSensitivityAnalysis(UUID studyUuid, UUID nodeUuid, String userId) Objects.requireNonNull(studyUuid); Objects.requireNonNull(nodeUuid); - Optional prevResultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, SENSITIVITY_ANALYSIS); - prevResultUuidOpt.ifPresent(sensitivityAnalysisService::deleteSensitivityAnalysisResult); + UUID prevResultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), SENSITIVITY_ANALYSIS); + if (prevResultUuid != null) { + sensitivityAnalysisService.deleteSensitivityAnalysisResult(prevResultUuid); + } StudyEntity study = studyRepository.findById(studyUuid).orElseThrow(() -> new StudyException(STUDY_NOT_FOUND)); UUID networkUuid = networkStoreService.getNetworkUuid(studyUuid); - String variantId = networkModificationTreeService.getVariantId(nodeUuid); - UUID sensiReportUuid = networkModificationTreeService.getComputationReports(nodeUuid).getOrDefault(SENSITIVITY_ANALYSIS.name(), UUID.randomUUID()); - networkModificationTreeService.updateComputationReportUuid(nodeUuid, SENSITIVITY_ANALYSIS, sensiReportUuid); + String variantId = networkModificationTreeService.getVariantId(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)); + UUID sensiReportUuid = networkModificationTreeService.getComputationReports(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)).getOrDefault(SENSITIVITY_ANALYSIS.name(), UUID.randomUUID()); + networkModificationTreeService.updateComputationReportUuid(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), SENSITIVITY_ANALYSIS, sensiReportUuid); - UUID result = sensitivityAnalysisService.runSensitivityAnalysis(nodeUuid, networkUuid, variantId, sensiReportUuid, userId, study.getSensitivityAnalysisParametersUuid(), study.getLoadFlowParametersUuid()); + UUID result = sensitivityAnalysisService.runSensitivityAnalysis(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), networkUuid, variantId, sensiReportUuid, userId, study.getSensitivityAnalysisParametersUuid(), study.getLoadFlowParametersUuid()); - updateComputationResultUuid(nodeUuid, result, SENSITIVITY_ANALYSIS); + updateComputationResultUuid(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), result, SENSITIVITY_ANALYSIS); notificationService.emitStudyChanged(studyUuid, nodeUuid, NotificationService.UPDATE_TYPE_SENSITIVITY_ANALYSIS_STATUS); return result; } - public UUID runShortCircuit(UUID studyUuid, UUID nodeUuid, Optional busId, String userId) { + public UUID runShortCircuit(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, Optional busId, String userId) { ComputationType computationType = busId.isEmpty() ? SHORT_CIRCUIT : SHORT_CIRCUIT_ONE_BUS; - networkModificationTreeService.getComputationResultUuid(nodeUuid, computationType) - .ifPresent(shortCircuitService::deleteShortCircuitAnalysisResult); + UUID shortCircuitResultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, computationType); + if (shortCircuitResultUuid != null) { + shortCircuitService.deleteShortCircuitAnalysisResult(shortCircuitResultUuid); + } final Optional parametersUuid = studyRepository.findById(studyUuid).map(StudyEntity::getShortCircuitParametersUuid); - UUID scReportUuid = networkModificationTreeService.getComputationReports(nodeUuid).getOrDefault(computationType.name(), UUID.randomUUID()); - networkModificationTreeService.updateComputationReportUuid(nodeUuid, computationType, scReportUuid); - final UUID result = shortCircuitService.runShortCircuit(studyUuid, nodeUuid, busId.orElse(null), parametersUuid, scReportUuid, userId); - updateComputationResultUuid(nodeUuid, result, computationType); + UUID scReportUuid = networkModificationTreeService.getComputationReports(nodeUuid, rootNetworkUuid).getOrDefault(computationType.name(), UUID.randomUUID()); + networkModificationTreeService.updateComputationReportUuid(nodeUuid, rootNetworkUuid, computationType, scReportUuid); + final UUID result = shortCircuitService.runShortCircuit(studyUuid, nodeUuid, rootNetworkUuid, busId.orElse(null), parametersUuid, scReportUuid, userId); + updateComputationResultUuid(nodeUuid, rootNetworkUuid, result, computationType); notificationService.emitStudyChanged(studyUuid, nodeUuid, busId.isEmpty() ? NotificationService.UPDATE_TYPE_SHORT_CIRCUIT_STATUS : NotificationService.UPDATE_TYPE_ONE_BUS_SHORT_CIRCUIT_STATUS); return result; } - public UUID runVoltageInit(UUID studyUuid, UUID nodeUuid, String userId) { - Optional prevResultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, VOLTAGE_INITIALIZATION); - prevResultUuidOpt.ifPresent(voltageInitService::deleteVoltageInitResult); + public UUID runVoltageInit(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, String userId) { + UUID prevResultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, VOLTAGE_INITIALIZATION); + if (prevResultUuid != null) { + voltageInitService.deleteVoltageInitResult(prevResultUuid); + } UUID networkUuid = networkStoreService.getNetworkUuid(studyUuid); - String variantId = networkModificationTreeService.getVariantId(nodeUuid); + String variantId = networkModificationTreeService.getVariantId(nodeUuid, rootNetworkUuid); StudyEntity studyEntity = studyRepository.findById(studyUuid).orElseThrow(() -> new StudyException(STUDY_NOT_FOUND)); - UUID reportUuid = networkModificationTreeService.getComputationReports(nodeUuid).getOrDefault(VOLTAGE_INITIALIZATION.name(), UUID.randomUUID()); - networkModificationTreeService.updateComputationReportUuid(nodeUuid, VOLTAGE_INITIALIZATION, reportUuid); - UUID result = voltageInitService.runVoltageInit(networkUuid, variantId, studyEntity.getVoltageInitParametersUuid(), reportUuid, nodeUuid, userId); + UUID reportUuid = networkModificationTreeService.getComputationReports(nodeUuid, rootNetworkUuid).getOrDefault(VOLTAGE_INITIALIZATION.name(), UUID.randomUUID()); + networkModificationTreeService.updateComputationReportUuid(nodeUuid, rootNetworkUuid, VOLTAGE_INITIALIZATION, reportUuid); + UUID result = voltageInitService.runVoltageInit(networkUuid, variantId, studyEntity.getVoltageInitParametersUuid(), reportUuid, nodeUuid, rootNetworkUuid, userId); - updateComputationResultUuid(nodeUuid, result, VOLTAGE_INITIALIZATION); + updateComputationResultUuid(nodeUuid, rootNetworkUuid, result, VOLTAGE_INITIALIZATION); notificationService.emitStudyChanged(studyUuid, nodeUuid, NotificationService.UPDATE_TYPE_VOLTAGE_INIT_STATUS); return result; } @@ -1937,19 +1968,21 @@ public void deleteDynamicSimulationEvents(UUID studyUuid, UUID nodeUuid, String } @Transactional - public UUID runDynamicSimulation(UUID studyUuid, UUID nodeUuid, DynamicSimulationParametersInfos parameters, String userId) { + public UUID runDynamicSimulation(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, DynamicSimulationParametersInfos parameters, String userId) { Objects.requireNonNull(studyUuid); Objects.requireNonNull(nodeUuid); // pre-condition check - String lfStatus = loadflowService.getLoadFlowStatus(nodeUuid); + String lfStatus = loadflowService.getLoadFlowStatus(nodeUuid, rootNetworkUuid); if (!LoadFlowStatus.CONVERGED.name().equals(lfStatus)) { throw new StudyException(NOT_ALLOWED, "Load flow must run successfully before running dynamic simulation"); } // clean previous result if exist - Optional prevResultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, DYNAMIC_SIMULATION); - prevResultUuidOpt.ifPresent(dynamicSimulationService::deleteResult); + UUID prevResultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, DYNAMIC_SIMULATION); + if (prevResultUuid != null) { + dynamicSimulationService.deleteResult(prevResultUuid); + } // load configured parameters persisted in the study server DB DynamicSimulationParametersInfos configuredParameters = getDynamicSimulationParameters(studyUuid); @@ -1968,55 +2001,56 @@ public UUID runDynamicSimulation(UUID studyUuid, UUID nodeUuid, DynamicSimulatio if (parameters != null) { PropertyUtils.copyNonNullProperties(parameters, mergeParameters); } - UUID reportUuid = networkModificationTreeService.getComputationReports(nodeUuid).getOrDefault(DYNAMIC_SIMULATION.name(), UUID.randomUUID()); - networkModificationTreeService.updateComputationReportUuid(nodeUuid, DYNAMIC_SIMULATION, reportUuid); + UUID reportUuid = networkModificationTreeService.getComputationReports(nodeUuid, rootNetworkUuid).getOrDefault(DYNAMIC_SIMULATION.name(), UUID.randomUUID()); + networkModificationTreeService.updateComputationReportUuid(nodeUuid, rootNetworkUuid, DYNAMIC_SIMULATION, reportUuid); // launch dynamic simulation - UUID resultUuid = dynamicSimulationService.runDynamicSimulation(getDynamicSimulationProvider(studyUuid), studyUuid, nodeUuid, reportUuid, mergeParameters, userId); + UUID resultUuid = dynamicSimulationService.runDynamicSimulation(getDynamicSimulationProvider(studyUuid), studyUuid, nodeUuid, rootNetworkUuid, reportUuid, mergeParameters, userId); // update result uuid and notification - updateComputationResultUuid(nodeUuid, resultUuid, DYNAMIC_SIMULATION); + updateComputationResultUuid(nodeUuid, rootNetworkUuid, resultUuid, DYNAMIC_SIMULATION); notificationService.emitStudyChanged(studyUuid, nodeUuid, NotificationService.UPDATE_TYPE_DYNAMIC_SIMULATION_STATUS); return resultUuid; } - public List getDynamicSimulationTimeSeriesMetadata(UUID nodeUuid) { - return dynamicSimulationService.getTimeSeriesMetadataList(nodeUuid); + public List getDynamicSimulationTimeSeriesMetadata(UUID nodeUuid, UUID rootNetworkUuid) { + return dynamicSimulationService.getTimeSeriesMetadataList(nodeUuid, rootNetworkUuid); } - public List getDynamicSimulationTimeSeries(UUID nodeUuid, List timeSeriesNames) { + public List getDynamicSimulationTimeSeries(UUID nodeUuid, UUID rootNetworkUuid, List timeSeriesNames) { // get timeseries from node uuid - return dynamicSimulationService.getTimeSeriesResult(nodeUuid, timeSeriesNames); + return dynamicSimulationService.getTimeSeriesResult(nodeUuid, rootNetworkUuid, timeSeriesNames); } - public List getDynamicSimulationTimeline(UUID nodeUuid) { + public List getDynamicSimulationTimeline(UUID nodeUuid, UUID rootNetworkUuid) { // get timeline from node uuid - return dynamicSimulationService.getTimelineResult(nodeUuid); // timeline has only one element + return dynamicSimulationService.getTimelineResult(nodeUuid, rootNetworkUuid); // timeline has only one element } - public DynamicSimulationStatus getDynamicSimulationStatus(UUID nodeUuid) { - return dynamicSimulationService.getStatus(nodeUuid); + public DynamicSimulationStatus getDynamicSimulationStatus(UUID nodeUuid, UUID rootNetworkUuid) { + return dynamicSimulationService.getStatus(nodeUuid, rootNetworkUuid); } // --- Dynamic Simulation service methods END --- // public String getNetworkElementsIds(UUID studyUuid, UUID nodeUuid, List substationsIds, boolean inUpstreamBuiltParentNode, String equipmentType, List nominalVoltages) { - UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, inUpstreamBuiltParentNode); - return networkMapService.getElementsIds(networkStoreService.getNetworkUuid(studyUuid), networkModificationTreeService.getVariantId(nodeUuidToSearchIn), + UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), inUpstreamBuiltParentNode); + return networkMapService.getElementsIds(networkStoreService.getNetworkUuid(studyUuid), networkModificationTreeService.getVariantId(nodeUuidToSearchIn, self.getStudyFirstRootNetworkUuid(studyUuid)), substationsIds, equipmentType, nominalVoltages); } @Transactional(readOnly = true) - public String getVoltageInitModifications(@NonNull UUID nodeUuid) { + public String getVoltageInitModifications(@NonNull UUID nodeUuid, @NonNull UUID rootNetworkUuid) { // get modifications group uuid associated to voltage init results - UUID voltageInitModificationsGroupUuid = voltageInitService.getModificationsGroupUuid(nodeUuid); + UUID voltageInitModificationsGroupUuid = voltageInitService.getModificationsGroupUuid(nodeUuid, rootNetworkUuid); return networkModificationService.getModifications(voltageInitModificationsGroupUuid, false, false); } + @Transactional public void copyVoltageInitModifications(UUID studyUuid, UUID nodeUuid, String userId) { // get modifications group uuid associated to voltage init results - UUID voltageInitModificationsGroupUuid = voltageInitService.getModificationsGroupUuid(nodeUuid); + UUID voltageInitModificationsGroupUuid = voltageInitService.getModificationsGroupUuid(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)); if (voltageInitModificationsGroupUuid == null) { return; } @@ -2025,16 +2059,17 @@ public void copyVoltageInitModifications(UUID studyUuid, UUID nodeUuid, String u notificationService.emitStartModificationEquipmentNotification(studyUuid, nodeUuid, childrenUuids, NotificationService.MODIFICATIONS_UPDATING_IN_PROGRESS); try { checkStudyContainsNode(studyUuid, nodeUuid); - NodeModificationInfos nodeInfos = networkModificationTreeService.getNodeModificationInfos(nodeUuid); + NetworkModificationNodeInfoEntity networkModificationNodeInfoEntity = networkModificationTreeService.getNetworkModificationNodeInfoEntity(nodeUuid); + RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = rootNetworkService.getRootNetworkNodeInfo(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)).orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND)); UUID networkUuid = networkStoreService.getNetworkUuid(studyUuid); - Optional networkModificationResult = networkModificationService.duplicateModificationsInGroup(voltageInitModificationsGroupUuid, networkUuid, nodeInfos); + Optional networkModificationResult = networkModificationService.duplicateModificationsInGroup(voltageInitModificationsGroupUuid, networkUuid, networkModificationNodeInfoEntity, rootNetworkNodeInfoEntity); - voltageInitService.resetModificationsGroupUuid(nodeUuid); + voltageInitService.resetModificationsGroupUuid(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)); // invalidate the whole subtree except the target node (we have built this node during the duplication) - networkModificationResult.ifPresent(modificationResult -> emitNetworkModificationImpacts(studyUuid, nodeUuid, modificationResult)); + networkModificationResult.ifPresent(modificationResult -> emitNetworkModificationImpacts(studyUuid, nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), modificationResult)); notificationService.emitStudyChanged(studyUuid, nodeUuid, NotificationService.UPDATE_TYPE_VOLTAGE_INIT_RESULT); // send notification voltage init result has changed - updateStatuses(studyUuid, nodeUuid, true, true, false); // do not delete the voltage init results + updateStatuses(studyUuid, nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), true, true, false); // do not delete the voltage init results } finally { notificationService.emitEndModificationEquipmentNotification(studyUuid, nodeUuid, childrenUuids); } @@ -2105,15 +2140,17 @@ public UUID runNonEvacuatedEnergy(UUID studyUuid, UUID nodeUuid, String userId) Objects.requireNonNull(studyUuid); Objects.requireNonNull(nodeUuid); StudyEntity studyEntity = studyRepository.findById(studyUuid).orElseThrow(() -> new StudyException(STUDY_NOT_FOUND)); - Optional prevResultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, NON_EVACUATED_ENERGY_ANALYSIS); + UUID prevResultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), NON_EVACUATED_ENERGY_ANALYSIS); - prevResultUuidOpt.ifPresent(nonEvacuatedEnergyService::deleteNonEvacuatedEnergyResult); + if (prevResultUuid != null) { + nonEvacuatedEnergyService.deleteNonEvacuatedEnergyResult(prevResultUuid); + } UUID networkUuid = networkStoreService.getNetworkUuid(studyUuid); String provider = getNonEvacuatedEnergyProvider(studyUuid); - String variantId = networkModificationTreeService.getVariantId(nodeUuid); - UUID reportUuid = networkModificationTreeService.getComputationReports(nodeUuid).getOrDefault(NON_EVACUATED_ENERGY_ANALYSIS.name(), UUID.randomUUID()); - networkModificationTreeService.updateComputationReportUuid(nodeUuid, NON_EVACUATED_ENERGY_ANALYSIS, reportUuid); + String variantId = networkModificationTreeService.getVariantId(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)); + UUID reportUuid = networkModificationTreeService.getComputationReports(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid)).getOrDefault(NON_EVACUATED_ENERGY_ANALYSIS.name(), UUID.randomUUID()); + networkModificationTreeService.updateComputationReportUuid(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), NON_EVACUATED_ENERGY_ANALYSIS, reportUuid); NonEvacuatedEnergyParametersInfos nonEvacuatedEnergyParametersInfos = getNonEvacuatedEnergyParametersInfos(studyUuid); SensitivityAnalysisParameters sensitivityAnalysisParameters = SensitivityAnalysisParameters.load(); @@ -2146,9 +2183,9 @@ public UUID runNonEvacuatedEnergy(UUID studyUuid, UUID nodeUuid, String userId) .filter(NonEvacuatedEnergyContingencies::isActivated) .collect(Collectors.toList())); - UUID result = nonEvacuatedEnergyService.runNonEvacuatedEnergy(nodeUuid, networkUuid, variantId, reportUuid, provider, nonEvacuatedEnergyInputData, studyEntity.getLoadFlowParametersUuid(), userId); + UUID result = nonEvacuatedEnergyService.runNonEvacuatedEnergy(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), networkUuid, variantId, reportUuid, provider, nonEvacuatedEnergyInputData, studyEntity.getLoadFlowParametersUuid(), userId); - updateComputationResultUuid(nodeUuid, result, NON_EVACUATED_ENERGY_ANALYSIS); + updateComputationResultUuid(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), result, NON_EVACUATED_ENERGY_ANALYSIS); notificationService.emitStudyChanged(studyUuid, nodeUuid, NotificationService.UPDATE_TYPE_NON_EVACUATED_ENERGY_STATUS); return result; } @@ -2182,8 +2219,8 @@ private void emitAllComputationStatusChanged(UUID studyUuid, UUID nodeUuid) { } public String evaluateFilter(UUID studyUuid, UUID nodeUuid, boolean inUpstreamBuiltParentNode, String filter) { - UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, inUpstreamBuiltParentNode); - return filterService.evaluateFilter(networkStoreService.getNetworkUuid(studyUuid), networkModificationTreeService.getVariantId(nodeUuidToSearchIn), filter); + UUID nodeUuidToSearchIn = getNodeUuidToSearchIn(nodeUuid, self.getStudyFirstRootNetworkUuid(studyUuid), inUpstreamBuiltParentNode); + return filterService.evaluateFilter(networkStoreService.getNetworkUuid(studyUuid), networkModificationTreeService.getVariantId(nodeUuidToSearchIn, self.getStudyFirstRootNetworkUuid(studyUuid)), filter); } public String exportFilter(UUID studyUuid, UUID filterUuid) { @@ -2192,7 +2229,7 @@ public String exportFilter(UUID studyUuid, UUID filterUuid) { } @Transactional - public UUID runStateEstimation(UUID studyUuid, UUID nodeUuid, String userId) { + public UUID runStateEstimation(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, String userId) { Objects.requireNonNull(studyUuid); Objects.requireNonNull(nodeUuid); if (studyRepository.findById(studyUuid).isEmpty()) { @@ -2200,23 +2237,35 @@ public UUID runStateEstimation(UUID studyUuid, UUID nodeUuid, String userId) { } UUID networkUuid = networkStoreService.getNetworkUuid(studyUuid); - String variantId = networkModificationTreeService.getVariantId(nodeUuid); - UUID reportUuid = networkModificationTreeService.getComputationReports(nodeUuid).getOrDefault(STATE_ESTIMATION.name(), UUID.randomUUID()); - networkModificationTreeService.updateComputationReportUuid(nodeUuid, STATE_ESTIMATION, reportUuid); + String variantId = networkModificationTreeService.getVariantId(nodeUuid, rootNetworkUuid); + UUID reportUuid = networkModificationTreeService.getComputationReports(nodeUuid, rootNetworkUuid).getOrDefault(STATE_ESTIMATION.name(), UUID.randomUUID()); + networkModificationTreeService.updateComputationReportUuid(nodeUuid, rootNetworkUuid, STATE_ESTIMATION, reportUuid); String receiver; try { - receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid)), StandardCharsets.UTF_8); + receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid, rootNetworkUuid)), StandardCharsets.UTF_8); } catch (JsonProcessingException e) { throw new UncheckedIOException(e); } - Optional prevResultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, STATE_ESTIMATION); - prevResultUuidOpt.ifPresent(stateEstimationService::deleteStateEstimationResult); + UUID prevResultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, STATE_ESTIMATION); + if (prevResultUuid != null) { + stateEstimationService.deleteStateEstimationResult(prevResultUuid); + } UUID result = stateEstimationService.runStateEstimation(networkUuid, variantId, new ReportInfos(reportUuid, nodeUuid), receiver, userId); - updateComputationResultUuid(nodeUuid, result, STATE_ESTIMATION); + updateComputationResultUuid(nodeUuid, rootNetworkUuid, result, STATE_ESTIMATION); notificationService.emitStudyChanged(studyUuid, nodeUuid, NotificationService.UPDATE_TYPE_STATE_ESTIMATION_STATUS); return result; } + public NetworkModificationNode createNode(UUID studyUuid, UUID nodeId, NetworkModificationNode nodeInfo, InsertMode insertMode, String userId) { + StudyEntity study = studyRepository.findById(studyUuid).orElseThrow(() -> new StudyException(STUDY_NOT_FOUND)); + return networkModificationTreeService.createNode(study, nodeId, nodeInfo, insertMode, userId); + } + + //TODO: temporary method, once frontend had been implemented, each operation will need to target a specific rootNetwork UUID, here we manually target the first one + @Transactional + public UUID getStudyFirstRootNetworkUuid(UUID studyUuid) { + return studyRepository.findById(studyUuid).orElseThrow(() -> new StudyException(STUDY_NOT_FOUND)).getFirstRootNetwork().getId(); + } } diff --git a/src/main/java/org/gridsuite/study/server/service/SupervisionService.java b/src/main/java/org/gridsuite/study/server/service/SupervisionService.java index 47f907fee..2ac889043 100644 --- a/src/main/java/org/gridsuite/study/server/service/SupervisionService.java +++ b/src/main/java/org/gridsuite/study/server/service/SupervisionService.java @@ -9,9 +9,11 @@ import org.gridsuite.study.server.StudyException; import org.gridsuite.study.server.elasticsearch.EquipmentInfosService; import org.gridsuite.study.server.networkmodificationtree.dto.RootNode; -import org.gridsuite.study.server.networkmodificationtree.entities.AbstractNodeInfoEntity; -import org.gridsuite.study.server.networkmodificationtree.entities.NetworkModificationNodeInfoEntity; -import org.gridsuite.study.server.repository.networkmodificationtree.NetworkModificationNodeInfoRepository; +import org.gridsuite.study.server.networkmodificationtree.entities.RootNetworkNodeInfoEntity; +import org.gridsuite.study.server.repository.StudyEntity; +import org.gridsuite.study.server.repository.StudyRepository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkEntity; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkNodeInfoRepository; import org.gridsuite.study.server.service.dynamicsimulation.DynamicSimulationService; import org.gridsuite.study.server.service.shortcircuit.ShortCircuitService; import org.slf4j.Logger; @@ -29,6 +31,7 @@ import java.util.stream.Stream; import static org.gridsuite.study.server.StudyException.Type.ELEMENT_NOT_FOUND; +import static org.gridsuite.study.server.StudyException.Type.STUDY_NOT_FOUND; /** * @author Hugo Marcellin @@ -63,14 +66,16 @@ public class SupervisionService { private final EquipmentInfosService equipmentInfosService; - private final NetworkModificationNodeInfoRepository networkModificationNodeInfoRepository; + private final RootNetworkNodeInfoRepository rootNetworkNodeInfoRepository; private final StateEstimationService stateEstimationService; + private final StudyRepository studyRepository; + public SupervisionService(StudyService studyService, NetworkModificationTreeService networkModificationTreeService, NetworkService networkStoreService, - NetworkModificationNodeInfoRepository networkModificationNodeInfoRepository, + RootNetworkNodeInfoRepository rootNetworkNodeInfoRepository, ReportService reportService, LoadFlowService loadFlowService, DynamicSimulationService dynamicSimulationService, @@ -80,11 +85,12 @@ public SupervisionService(StudyService studyService, ShortCircuitService shortCircuitService, VoltageInitService voltageInitService, EquipmentInfosService equipmentInfosService, - StateEstimationService stateEstimationService) { + StateEstimationService stateEstimationService, + StudyRepository studyRepository) { this.networkStoreService = networkStoreService; this.studyService = studyService; this.networkModificationTreeService = networkModificationTreeService; - this.networkModificationNodeInfoRepository = networkModificationNodeInfoRepository; + this.rootNetworkNodeInfoRepository = rootNetworkNodeInfoRepository; this.reportService = reportService; this.loadFlowService = loadFlowService; this.dynamicSimulationService = dynamicSimulationService; @@ -95,6 +101,7 @@ public SupervisionService(StudyService studyService, this.voltageInitService = voltageInitService; this.equipmentInfosService = equipmentInfosService; this.stateEstimationService = stateEstimationService; + this.studyRepository = studyRepository; } @Transactional @@ -152,112 +159,113 @@ public Long deleteStudyIndexedEquipmentsAndTombstoned(UUID studyUuid) { private Integer deleteLoadflowResults() { AtomicReference startTime = new AtomicReference<>(); startTime.set(System.nanoTime()); - List nodes = networkModificationNodeInfoRepository.findAllByLoadFlowResultUuidNotNull(); + List rootNetworkNodeInfoEntities = rootNetworkNodeInfoRepository.findAllByLoadFlowResultUuidNotNull(); List reportsToDelete = new ArrayList<>(); - nodes.forEach(node -> { - node.setLoadFlowResultUuid(null); - reportsToDelete.add(node.getComputationReports().get(ComputationType.LOAD_FLOW.name())); - node.getComputationReports().remove(ComputationType.LOAD_FLOW.name()); + rootNetworkNodeInfoEntities.forEach(rootNetworkNodeInfo -> { + rootNetworkNodeInfo.setLoadFlowResultUuid(null); + reportsToDelete.add(rootNetworkNodeInfo.getComputationReports().get(ComputationType.LOAD_FLOW.name())); + rootNetworkNodeInfo.getComputationReports().remove(ComputationType.LOAD_FLOW.name()); }); reportService.deleteReports(reportsToDelete); loadFlowService.deleteLoadFlowResults(); LOGGER.trace(DELETION_LOG_MESSAGE, ComputationType.LOAD_FLOW, TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime.get())); - return nodes.size(); + return rootNetworkNodeInfoEntities.size(); } private Integer deleteDynamicSimulationResults() { AtomicReference startTime = new AtomicReference<>(); startTime.set(System.nanoTime()); - List nodes = networkModificationNodeInfoRepository.findAllByDynamicSimulationResultUuidNotNull(); - nodes.forEach(node -> node.setShortCircuitAnalysisResultUuid(null)); + List rootNetworkNodeStatusEntities = rootNetworkNodeInfoRepository.findAllByDynamicSimulationResultUuidNotNull(); + rootNetworkNodeStatusEntities.forEach(rootNetworkNodeStatus -> rootNetworkNodeStatus.setDynamicSimulationResultUuid(null)); //TODO Add logs deletion once they are added dynamicSimulationService.deleteResults(); LOGGER.trace(DELETION_LOG_MESSAGE, ComputationType.DYNAMIC_SIMULATION, TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime.get())); - return nodes.size(); + return rootNetworkNodeStatusEntities.size(); } private Integer deleteSecurityAnalysisResults() { AtomicReference startTime = new AtomicReference<>(); startTime.set(System.nanoTime()); - List nodes = networkModificationNodeInfoRepository.findAllBySecurityAnalysisResultUuidNotNull(); + List rootNetworkNodeInfoEntities = rootNetworkNodeInfoRepository.findAllBySecurityAnalysisResultUuidNotNull(); List reportsToDelete = new ArrayList<>(); - nodes.forEach(node -> { - node.setSecurityAnalysisResultUuid(null); - reportsToDelete.add(node.getComputationReports().get(ComputationType.SECURITY_ANALYSIS.name())); - node.getComputationReports().remove(ComputationType.SECURITY_ANALYSIS.name()); + rootNetworkNodeInfoEntities.forEach(rootNetworkNodeInfo -> { + rootNetworkNodeInfo.setSecurityAnalysisResultUuid(null); + reportsToDelete.add(rootNetworkNodeInfo.getComputationReports().get(ComputationType.SECURITY_ANALYSIS.name())); + rootNetworkNodeInfo.getComputationReports().remove(ComputationType.SECURITY_ANALYSIS.name()); }); reportService.deleteReports(reportsToDelete); securityAnalysisService.deleteSecurityAnalysisResults(); LOGGER.trace(DELETION_LOG_MESSAGE, ComputationType.SECURITY_ANALYSIS, TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime.get())); - return nodes.size(); + return rootNetworkNodeInfoEntities.size(); } private Integer deleteSensitivityAnalysisResults() { AtomicReference startTime = new AtomicReference<>(); startTime.set(System.nanoTime()); - List nodes = networkModificationNodeInfoRepository.findAllBySensitivityAnalysisResultUuidNotNull(); + List rootNetworkNodeInfoEntities = rootNetworkNodeInfoRepository.findAllBySensitivityAnalysisResultUuidNotNull(); List reportsToDelete = new ArrayList<>(); - nodes.forEach(node -> { - node.setSensitivityAnalysisResultUuid(null); - reportsToDelete.add(node.getComputationReports().get(ComputationType.SENSITIVITY_ANALYSIS.name())); - node.getComputationReports().remove(ComputationType.SENSITIVITY_ANALYSIS.name()); + rootNetworkNodeInfoEntities.forEach(rootNetworkNodeInfo -> { + rootNetworkNodeInfo.setSensitivityAnalysisResultUuid(null); + reportsToDelete.add(rootNetworkNodeInfo.getComputationReports().get(ComputationType.SENSITIVITY_ANALYSIS.name())); + rootNetworkNodeInfo.getComputationReports().remove(ComputationType.SENSITIVITY_ANALYSIS.name()); }); reportService.deleteReports(reportsToDelete); sensitivityAnalysisService.deleteSensitivityAnalysisResults(); - LOGGER.trace(DELETION_LOG_MESSAGE, ComputationType.SENSITIVITY_ANALYSIS, TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime.get())); - return nodes.size(); + return rootNetworkNodeInfoEntities.size(); } private Integer deleteNonEvacuatedEnergyAnalysisResults() { AtomicReference startTime = new AtomicReference<>(); startTime.set(System.nanoTime()); - List nodes = networkModificationNodeInfoRepository.findAllByNonEvacuatedEnergyResultUuidNotNull(); + List rootNetworkNodeInfoEntities = rootNetworkNodeInfoRepository.findAllByNonEvacuatedEnergyResultUuidNotNull(); List reportsToDelete = new ArrayList<>(); - nodes.forEach(node -> { - node.setNonEvacuatedEnergyResultUuid(null); - reportsToDelete.add(node.getComputationReports().get(ComputationType.NON_EVACUATED_ENERGY_ANALYSIS.name())); - node.getComputationReports().remove(ComputationType.NON_EVACUATED_ENERGY_ANALYSIS.name()); + rootNetworkNodeInfoEntities.forEach(rootNetworkNodeInfo -> { + rootNetworkNodeInfo.setNonEvacuatedEnergyResultUuid(null); + reportsToDelete.add(rootNetworkNodeInfo.getComputationReports().get(ComputationType.NON_EVACUATED_ENERGY_ANALYSIS.name())); + rootNetworkNodeInfo.getComputationReports().remove(ComputationType.NON_EVACUATED_ENERGY_ANALYSIS.name()); }); reportService.deleteReports(reportsToDelete); nonEvacuatedEnergyService.deleteNonEvacuatedEnergyResults(); LOGGER.trace(DELETION_LOG_MESSAGE, ComputationType.NON_EVACUATED_ENERGY_ANALYSIS, TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime.get())); - return nodes.size(); + return rootNetworkNodeInfoEntities.size(); } private Integer deleteShortcircuitResults() { AtomicReference startTime = new AtomicReference<>(); startTime.set(System.nanoTime()); // Reset result uuid and remove logs, for all-buses computations, then for 1-bus ones - List allBusesNodes = networkModificationNodeInfoRepository.findAllByShortCircuitAnalysisResultUuidNotNull(); - if (!allBusesNodes.isEmpty()) { + List allBusesrootNetworkNodeInfoEntities = rootNetworkNodeInfoRepository.findAllByShortCircuitAnalysisResultUuidNotNull(); + if (!allBusesrootNetworkNodeInfoEntities.isEmpty()) { List reportsToDelete = new ArrayList<>(); - allBusesNodes.forEach(node -> { - node.setShortCircuitAnalysisResultUuid(null); - reportsToDelete.add(node.getComputationReports().get(ComputationType.SHORT_CIRCUIT.name())); - node.getComputationReports().remove(ComputationType.SHORT_CIRCUIT.name()); + allBusesrootNetworkNodeInfoEntities.forEach(rootNetworkNodeInfo -> { + rootNetworkNodeInfo.setShortCircuitAnalysisResultUuid(null); + reportsToDelete.add(rootNetworkNodeInfo.getComputationReports().get(ComputationType.SHORT_CIRCUIT.name())); + rootNetworkNodeInfo.getComputationReports().remove(ComputationType.SHORT_CIRCUIT.name()); }); reportService.deleteReports(reportsToDelete); } - List oneBusNodes = networkModificationNodeInfoRepository.findAllByOneBusShortCircuitAnalysisResultUuidNotNull(); - if (!oneBusNodes.isEmpty()) { + + List oneBusrootNetworkNodeInfoEntities = rootNetworkNodeInfoRepository.findAllByOneBusShortCircuitAnalysisResultUuidNotNull(); + if (!oneBusrootNetworkNodeInfoEntities.isEmpty()) { List reportsToDelete = new ArrayList<>(); - oneBusNodes.forEach(node -> { - node.setOneBusShortCircuitAnalysisResultUuid(null); - reportsToDelete.add(node.getComputationReports().get(ComputationType.SHORT_CIRCUIT_ONE_BUS.name())); - node.getComputationReports().remove(ComputationType.SHORT_CIRCUIT_ONE_BUS.name()); + oneBusrootNetworkNodeInfoEntities.forEach(rootNetworkNodeInfo -> { + rootNetworkNodeInfo.setOneBusShortCircuitAnalysisResultUuid(null); + reportsToDelete.add(rootNetworkNodeInfo.getComputationReports().get(ComputationType.SHORT_CIRCUIT_ONE_BUS.name())); + rootNetworkNodeInfo.getComputationReports().remove(ComputationType.SHORT_CIRCUIT_ONE_BUS.name()); }); reportService.deleteReports(reportsToDelete); } + // Then delete all results (1-bus and all-buses), cause short-circuit-server cannot make the difference shortCircuitService.deleteShortCircuitAnalysisResults(); LOGGER.trace(DELETION_LOG_MESSAGE, ComputationType.SHORT_CIRCUIT, TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime.get())); - // return distinct processed nodes count - return (int) Stream.concat(allBusesNodes.stream(), oneBusNodes.stream()) - .map(AbstractNodeInfoEntity::getId) + // return distinct processed time point node info count + return (int) Stream.concat(allBusesrootNetworkNodeInfoEntities.stream(), oneBusrootNetworkNodeInfoEntities.stream()) + .map(RootNetworkNodeInfoEntity::getId) .distinct() .count(); } @@ -265,35 +273,35 @@ private Integer deleteShortcircuitResults() { private Integer deleteVoltageInitResults() { AtomicReference startTime = new AtomicReference<>(); startTime.set(System.nanoTime()); - List nodes = networkModificationNodeInfoRepository.findAllByVoltageInitResultUuidNotNull(); - if (!nodes.isEmpty()) { + List rootNetworkNodeInfoEntities = rootNetworkNodeInfoRepository.findAllByVoltageInitResultUuidNotNull(); + if (!rootNetworkNodeInfoEntities.isEmpty()) { List reportsToDelete = new ArrayList<>(); - nodes.forEach(node -> { - node.setVoltageInitResultUuid(null); - reportsToDelete.add(node.getComputationReports().get(ComputationType.VOLTAGE_INITIALIZATION.name())); - node.getComputationReports().remove(ComputationType.VOLTAGE_INITIALIZATION.name()); + rootNetworkNodeInfoEntities.forEach(rootNetworkNodeInfo -> { + rootNetworkNodeInfo.setVoltageInitResultUuid(null); + reportsToDelete.add(rootNetworkNodeInfo.getComputationReports().get(ComputationType.VOLTAGE_INITIALIZATION.name())); + rootNetworkNodeInfo.getComputationReports().remove(ComputationType.VOLTAGE_INITIALIZATION.name()); }); reportService.deleteReports(reportsToDelete); } voltageInitService.deleteVoltageInitResults(); LOGGER.trace(DELETION_LOG_MESSAGE, ComputationType.VOLTAGE_INITIALIZATION, TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime.get())); - return nodes.size(); + return rootNetworkNodeInfoEntities.size(); } private Integer deleteStateEstimationResults() { AtomicReference startTime = new AtomicReference<>(); startTime.set(System.nanoTime()); - List nodes = networkModificationNodeInfoRepository.findAllByStateEstimationResultUuidNotNull(); + List rootNetworkNodeInfoEntities = rootNetworkNodeInfoRepository.findAllByStateEstimationResultUuidNotNull(); List reportsToDelete = new ArrayList<>(); - nodes.forEach(node -> { - node.setStateEstimationResultUuid(null); - reportsToDelete.add(node.getComputationReports().get(ComputationType.STATE_ESTIMATION.name())); - node.getComputationReports().remove(ComputationType.STATE_ESTIMATION.name()); + rootNetworkNodeInfoEntities.forEach(rootNetworkNodeInfo -> { + rootNetworkNodeInfo.setStateEstimationResultUuid(null); + reportsToDelete.add(rootNetworkNodeInfo.getComputationReports().get(ComputationType.STATE_ESTIMATION.name())); + rootNetworkNodeInfo.getComputationReports().remove(ComputationType.STATE_ESTIMATION.name()); }); reportService.deleteReports(reportsToDelete); stateEstimationService.deleteStateEstimationResults(); LOGGER.trace(DELETION_LOG_MESSAGE, ComputationType.STATE_ESTIMATION, TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime.get())); - return nodes.size(); + return rootNetworkNodeInfoEntities.size(); } @Transactional @@ -301,7 +309,8 @@ public void invalidateAllNodesBuilds(UUID studyUuid) { AtomicReference startTime = new AtomicReference<>(); startTime.set(System.nanoTime()); RootNode rootNode = networkModificationTreeService.getStudyTree(studyUuid); - studyService.invalidateBuild(studyUuid, rootNode.getId(), false, false, true); + RootNetworkEntity rootNetworkEntity = studyRepository.findById(studyUuid).map(StudyEntity::getFirstRootNetwork).orElseThrow(() -> new StudyException(STUDY_NOT_FOUND)); + studyService.invalidateBuild(studyUuid, rootNode.getId(), rootNetworkEntity.getId(), false, false, true); LOGGER.trace("Nodes builds deletion for study {} in : {} seconds", studyUuid, TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime.get())); } } diff --git a/src/main/java/org/gridsuite/study/server/service/VoltageInitService.java b/src/main/java/org/gridsuite/study/server/service/VoltageInitService.java index 18e6581b0..a14f3172f 100644 --- a/src/main/java/org/gridsuite/study/server/service/VoltageInitService.java +++ b/src/main/java/org/gridsuite/study/server/service/VoltageInitService.java @@ -28,7 +28,6 @@ import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Objects; -import java.util.Optional; import java.util.UUID; import static org.gridsuite.study.server.StudyConstants.*; @@ -64,11 +63,11 @@ public VoltageInitService(RemoteServicesProperties remoteServicesProperties, this.objectMapper = objectMapper; } - public UUID runVoltageInit(UUID networkUuid, String variantId, UUID parametersUuid, UUID reportUuid, UUID nodeUuid, String userId) { + public UUID runVoltageInit(UUID networkUuid, String variantId, UUID parametersUuid, UUID reportUuid, UUID nodeUuid, UUID rootNetworkUuid, String userId) { String receiver; try { - receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid)), StandardCharsets.UTF_8); + receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid, rootNetworkUuid)), StandardCharsets.UTF_8); } catch (JsonProcessingException e) { throw new UncheckedIOException(e); } @@ -96,16 +95,16 @@ public UUID runVoltageInit(UUID networkUuid, String variantId, UUID parametersUu return restTemplate.exchange(voltageInitServerBaseUri + path, HttpMethod.POST, new HttpEntity<>(headers), UUID.class).getBody(); } - private String getVoltageInitResultOrStatus(UUID nodeUuid, String suffix) { + private String getVoltageInitResultOrStatus(UUID nodeUuid, UUID rootNetworkUuid, String suffix) { String result; - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.VOLTAGE_INITIALIZATION); + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.VOLTAGE_INITIALIZATION); - if (resultUuidOpt.isEmpty()) { + if (resultUuid == null) { return null; } String path = UriComponentsBuilder.fromPath(DELIMITER + VOLTAGE_INIT_API_VERSION + "/results/{resultUuid}" + suffix) - .buildAndExpand(resultUuidOpt.get()).toUriString(); + .buildAndExpand(resultUuid).toUriString(); try { result = restTemplate.getForObject(voltageInitServerBaseUri + path, String.class); @@ -118,12 +117,12 @@ private String getVoltageInitResultOrStatus(UUID nodeUuid, String suffix) { return result; } - public String getVoltageInitResult(UUID nodeUuid) { - return getVoltageInitResultOrStatus(nodeUuid, ""); + public String getVoltageInitResult(UUID nodeUuid, UUID rootNetworkUuid) { + return getVoltageInitResultOrStatus(nodeUuid, rootNetworkUuid, ""); } - public String getVoltageInitStatus(UUID nodeUuid) { - return getVoltageInitResultOrStatus(nodeUuid, "/status"); + public String getVoltageInitStatus(UUID nodeUuid, UUID rootNetworkUuid) { + return getVoltageInitResultOrStatus(nodeUuid, rootNetworkUuid, "/status"); } public VoltageInitParametersInfos getVoltageInitParameters(UUID parametersUuid) { @@ -213,19 +212,19 @@ public void deleteVoltageInitParameters(UUID parametersUuid) { restTemplate.delete(voltageInitServerBaseUri + path); } - public void stopVoltageInit(UUID studyUuid, UUID nodeUuid, String userId) { + public void stopVoltageInit(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, String userId) { Objects.requireNonNull(studyUuid); Objects.requireNonNull(nodeUuid); Objects.requireNonNull(userId); - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.VOLTAGE_INITIALIZATION); - if (resultUuidOpt.isEmpty()) { + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.VOLTAGE_INITIALIZATION); + if (resultUuid == null) { return; } String receiver; try { - receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid)), StandardCharsets.UTF_8); + receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid, rootNetworkUuid)), StandardCharsets.UTF_8); } catch (JsonProcessingException e) { throw new UncheckedIOException(e); } @@ -236,7 +235,7 @@ public void stopVoltageInit(UUID studyUuid, UUID nodeUuid, String userId) { String path = UriComponentsBuilder .fromPath(DELIMITER + VOLTAGE_INIT_API_VERSION + "/results/{resultUuid}/stop") - .queryParam(QUERY_PARAM_RECEIVER, receiver).buildAndExpand(resultUuidOpt.get()).toUriString(); + .queryParam(QUERY_PARAM_RECEIVER, receiver).buildAndExpand(resultUuid).toUriString(); restTemplate.exchange(voltageInitServerBaseUri + path, HttpMethod.PUT, new HttpEntity<>(headers), Void.class); } @@ -269,22 +268,22 @@ public Integer getVoltageInitResultsCount() { return restTemplate.getForObject(voltageInitServerBaseUri + path, Integer.class); } - public void assertVoltageInitNotRunning(UUID nodeUuid) { - String scs = getVoltageInitStatus(nodeUuid); + public void assertVoltageInitNotRunning(UUID nodeUuid, UUID rootNetworkUuid) { + String scs = getVoltageInitStatus(nodeUuid, rootNetworkUuid); if (VoltageInitStatus.RUNNING.name().equals(scs)) { throw new StudyException(VOLTAGE_INIT_RUNNING); } } - public UUID getModificationsGroupUuid(UUID nodeUuid) { - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.VOLTAGE_INITIALIZATION); - if (resultUuidOpt.isEmpty()) { + public UUID getModificationsGroupUuid(UUID nodeUuid, UUID rootNetworkUuid) { + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.VOLTAGE_INITIALIZATION); + if (resultUuid == null) { throw new StudyException(NO_VOLTAGE_INIT_RESULTS_FOR_NODE, THE_NODE + nodeUuid + " has no voltage init results"); } UUID modificationsGroupUuid; String path = UriComponentsBuilder.fromPath(DELIMITER + VOLTAGE_INIT_API_VERSION + "/results/{resultUuid}/modifications-group-uuid") - .buildAndExpand(resultUuidOpt.get()).toUriString(); + .buildAndExpand(resultUuid).toUriString(); try { modificationsGroupUuid = restTemplate.getForObject(voltageInitServerBaseUri + path, UUID.class); } catch (HttpStatusCodeException e) { @@ -306,13 +305,13 @@ public void invalidateVoltageInitStatus(List uuids) { } } - public void resetModificationsGroupUuid(UUID nodeUuid) { - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.VOLTAGE_INITIALIZATION); - if (resultUuidOpt.isEmpty()) { + public void resetModificationsGroupUuid(UUID nodeUuid, UUID rootNetworkUuid) { + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.VOLTAGE_INITIALIZATION); + if (resultUuid == null) { throw new StudyException(NO_VOLTAGE_INIT_RESULTS_FOR_NODE, THE_NODE + nodeUuid + " has no voltage init results"); } String path = UriComponentsBuilder.fromPath(DELIMITER + VOLTAGE_INIT_API_VERSION + "/results/{resultUuid}/modifications-group-uuid") - .buildAndExpand(resultUuidOpt.get()).toUriString(); + .buildAndExpand(resultUuid).toUriString(); restTemplate.put(voltageInitServerBaseUri + path, Void.class); } diff --git a/src/main/java/org/gridsuite/study/server/service/dynamicsimulation/DynamicSimulationService.java b/src/main/java/org/gridsuite/study/server/service/dynamicsimulation/DynamicSimulationService.java index b7f350004..122fe4988 100644 --- a/src/main/java/org/gridsuite/study/server/service/dynamicsimulation/DynamicSimulationService.java +++ b/src/main/java/org/gridsuite/study/server/service/dynamicsimulation/DynamicSimulationService.java @@ -228,7 +228,7 @@ static NetworkInfos getDefaultNetwork() { * @param userId id of user * @return the UUID of the dynamic simulation */ - UUID runDynamicSimulation(String provider, UUID studyUuid, UUID nodeUuid, UUID reportUuid, DynamicSimulationParametersInfos parameters, String userId); + UUID runDynamicSimulation(String provider, UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, UUID reportUuid, DynamicSimulationParametersInfos parameters, String userId); /** * Get a list of curves from a given node UUID @@ -237,7 +237,7 @@ static NetworkInfos getDefaultNetwork() { * @param timeSeriesNames a given list of time-series names * @return a list of curves */ - List getTimeSeriesResult(UUID nodeUuid, List timeSeriesNames); + List getTimeSeriesResult(UUID nodeUuid, UUID rootNetworkUuid, List timeSeriesNames); /** * Get timeline from a given node UUID @@ -245,14 +245,14 @@ static NetworkInfos getDefaultNetwork() { * @param nodeUuid a given node UUID * @return a list of {@link TimelineEventInfos} */ - List getTimelineResult(UUID nodeUuid); + List getTimelineResult(UUID nodeUuid, UUID rootNetworkUuid); /** * Get the current status of the simulation * @param nodeUuid a given node UUID * @return the status of the dynamic simulation */ - DynamicSimulationStatus getStatus(UUID nodeUuid); + DynamicSimulationStatus getStatus(UUID nodeUuid, UUID rootNetworkUuid); /** * invalidate status of the simulation results @@ -280,7 +280,7 @@ static NetworkInfos getDefaultNetwork() { * @param nodeUuid a given node UUID * @throws StudyException with type DYNAMIC_SIMULATION_RUNNING if this node is in RUNNING status */ - void assertDynamicSimulationNotRunning(UUID nodeUuid); + void assertDynamicSimulationNotRunning(UUID nodeUuid, UUID rootNetworkUuid); /** * Get mapping names @@ -294,7 +294,7 @@ static NetworkInfos getDefaultNetwork() { * @param nodeUuid a given node UUID * @return a list of time-series metadata */ - List getTimeSeriesMetadataList(UUID nodeUuid); + List getTimeSeriesMetadataList(UUID nodeUuid, UUID rootNetworkUuid); /** * Get models used in the given mapping diff --git a/src/main/java/org/gridsuite/study/server/service/dynamicsimulation/impl/DynamicSimulationServiceImpl.java b/src/main/java/org/gridsuite/study/server/service/dynamicsimulation/impl/DynamicSimulationServiceImpl.java index 98fe86c59..184e39b90 100644 --- a/src/main/java/org/gridsuite/study/server/service/dynamicsimulation/impl/DynamicSimulationServiceImpl.java +++ b/src/main/java/org/gridsuite/study/server/service/dynamicsimulation/impl/DynamicSimulationServiceImpl.java @@ -76,14 +76,14 @@ public DynamicSimulationServiceImpl(ObjectMapper objectMapper, } @Override - public UUID runDynamicSimulation(String provider, UUID studyUuid, UUID nodeUuid, UUID reportUuid, DynamicSimulationParametersInfos parameters, String userId) { + public UUID runDynamicSimulation(String provider, UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, UUID reportUuid, DynamicSimulationParametersInfos parameters, String userId) { UUID networkUuid = networkService.getNetworkUuid(studyUuid); - String variantId = networkModificationTreeService.getVariantId(nodeUuid); + String variantId = networkModificationTreeService.getVariantId(nodeUuid, rootNetworkUuid); // create receiver for getting back the notification in rabbitmq String receiver; try { - receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid)), + receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid, rootNetworkUuid)), StandardCharsets.UTF_8); } catch (JsonProcessingException e) { throw new UncheckedIOException(e); @@ -93,13 +93,13 @@ public UUID runDynamicSimulation(String provider, UUID studyUuid, UUID nodeUuid, } @Override - public List getTimeSeriesMetadataList(UUID nodeUuid) { + public List getTimeSeriesMetadataList(UUID nodeUuid, UUID rootNetworkUuid) { List metadataList = new ArrayList<>(); - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.DYNAMIC_SIMULATION); + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.DYNAMIC_SIMULATION); - if (resultUuidOpt.isPresent()) { - UUID timeSeriesUuid = dynamicSimulationClient.getTimeSeriesResult(resultUuidOpt.get()); // get timeseries uuid + if (resultUuid != null) { + UUID timeSeriesUuid = dynamicSimulationClient.getTimeSeriesResult(resultUuid); // get timeseries uuid if (timeSeriesUuid != null) { // get timeseries metadata TimeSeriesGroupRest timeSeriesGroupMetadata = timeSeriesClient.getTimeSeriesGroupMetadata(timeSeriesUuid); @@ -119,13 +119,13 @@ public List getTimeSeriesMetadataList(UUID nodeUuid) { } @Override - public List getTimeSeriesResult(UUID nodeUuid, List timeSeriesNames) { + public List getTimeSeriesResult(UUID nodeUuid, UUID rootNetworkUuid, List timeSeriesNames) { List timeSeries = new ArrayList<>(); - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.DYNAMIC_SIMULATION); + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.DYNAMIC_SIMULATION); - if (resultUuidOpt.isPresent()) { - UUID timeSeriesUuid = dynamicSimulationClient.getTimeSeriesResult(resultUuidOpt.get()); // get timeseries uuid + if (resultUuid != null) { + UUID timeSeriesUuid = dynamicSimulationClient.getTimeSeriesResult(resultUuid); // get timeseries uuid if (timeSeriesUuid != null) { // get timeseries data timeSeries = timeSeriesClient.getTimeSeriesGroup(timeSeriesUuid, timeSeriesNames); @@ -144,11 +144,11 @@ public List getTimeSeriesResult(UUID nodeUuid, List ti } @Override - public List getTimelineResult(UUID nodeUuid) { - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.DYNAMIC_SIMULATION); + public List getTimelineResult(UUID nodeUuid, UUID rootNetworkUuid) { + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.DYNAMIC_SIMULATION); - if (resultUuidOpt.isPresent()) { - UUID timelineUuid = dynamicSimulationClient.getTimelineResult(resultUuidOpt.get()); // get timeline uuid + if (resultUuid != null) { + UUID timelineUuid = dynamicSimulationClient.getTimelineResult(resultUuid); // get timeline uuid if (timelineUuid != null) { // get timeline data List timelines = timeSeriesClient.getTimeSeriesGroup(timelineUuid, null); @@ -179,10 +179,12 @@ public List getTimelineResult(UUID nodeUuid) { } @Override - public DynamicSimulationStatus getStatus(UUID nodeUuid) { - return networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.DYNAMIC_SIMULATION) - .map(dynamicSimulationClient::getStatus) - .orElse(null); + public DynamicSimulationStatus getStatus(UUID nodeUuid, UUID rootNetworkUuid) { + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.DYNAMIC_SIMULATION); + if (resultUuid == null) { + return null; + } + return dynamicSimulationClient.getStatus(resultUuid); } @Override @@ -216,8 +218,8 @@ public Integer getResultsCount() { } @Override - public void assertDynamicSimulationNotRunning(UUID nodeUuid) { - DynamicSimulationStatus status = getStatus(nodeUuid); + public void assertDynamicSimulationNotRunning(UUID nodeUuid, UUID rootNetworkUuid) { + DynamicSimulationStatus status = getStatus(nodeUuid, rootNetworkUuid); if (DynamicSimulationStatus.RUNNING == status) { throw new StudyException(DYNAMIC_SIMULATION_RUNNING); } diff --git a/src/main/java/org/gridsuite/study/server/service/shortcircuit/ShortCircuitService.java b/src/main/java/org/gridsuite/study/server/service/shortcircuit/ShortCircuitService.java index 95e5b1384..336d65022 100644 --- a/src/main/java/org/gridsuite/study/server/service/shortcircuit/ShortCircuitService.java +++ b/src/main/java/org/gridsuite/study/server/service/shortcircuit/ShortCircuitService.java @@ -74,13 +74,13 @@ public ShortCircuitService(RemoteServicesProperties remoteServicesProperties, this.objectMapper = objectMapper; } - public UUID runShortCircuit(UUID studyUuid, UUID nodeUuid, String busId, Optional parametersUuid, UUID reportUuid, String userId) { + public UUID runShortCircuit(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, String busId, Optional parametersUuid, UUID reportUuid, String userId) { UUID networkUuid = networkStoreService.getNetworkUuid(studyUuid); - String variantId = getVariantId(nodeUuid); + String variantId = getVariantId(nodeUuid, rootNetworkUuid); String receiver; try { - receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid)), StandardCharsets.UTF_8); + receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid, rootNetworkUuid)), StandardCharsets.UTF_8); } catch (JsonProcessingException e) { throw new UncheckedIOException(e); } @@ -112,15 +112,17 @@ public UUID runShortCircuit(UUID studyUuid, UUID nodeUuid, String busId, Optiona return restTemplate.exchange(shortCircuitServerBaseUri + path, HttpMethod.POST, httpEntity, UUID.class).getBody(); } - private String getShortCircuitAnalysisResultResourcePath(UUID nodeUuid, ShortcircuitAnalysisType type) { - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, + private String getShortCircuitAnalysisResultResourcePath(UUID nodeUuid, UUID rootNetworkUuid, ShortcircuitAnalysisType type) { + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, type == ShortcircuitAnalysisType.ALL_BUSES ? ComputationType.SHORT_CIRCUIT : ComputationType.SHORT_CIRCUIT_ONE_BUS); - - return resultUuidOpt.map(uuid -> UriComponentsBuilder.fromPath(DELIMITER + SHORT_CIRCUIT_API_VERSION + "/results" + "/{resultUuid}").buildAndExpand(uuid).toUriString()).orElse(null); + if (resultUuid == null) { + return null; + } + return UriComponentsBuilder.fromPath(DELIMITER + SHORT_CIRCUIT_API_VERSION + "/results" + "/{resultUuid}").buildAndExpand(resultUuid).toUriString(); } - private String getShortCircuitAnalysisResultsPageResourcePath(UUID nodeUuid, ShortcircuitAnalysisType type) { - String resultPath = getShortCircuitAnalysisResultResourcePath(nodeUuid, type); + private String getShortCircuitAnalysisResultsPageResourcePath(UUID nodeUuid, UUID rootNetworkUuid, ShortcircuitAnalysisType type) { + String resultPath = getShortCircuitAnalysisResultResourcePath(nodeUuid, rootNetworkUuid, type); if (resultPath == null) { return null; } @@ -132,22 +134,22 @@ private String getShortCircuitAnalysisResultsPageResourcePath(UUID nodeUuid, Sho return resultPath + "/paged"; } - public String getShortCircuitAnalysisResult(UUID nodeUuid, FaultResultsMode mode, ShortcircuitAnalysisType type, String filters, boolean paged, Pageable pageable) { + public String getShortCircuitAnalysisResult(UUID nodeUuid, UUID rootNetworkUuid, FaultResultsMode mode, ShortcircuitAnalysisType type, String filters, boolean paged, Pageable pageable) { if (paged) { - return getShortCircuitAnalysisResultsPage(nodeUuid, mode, type, filters, pageable); + return getShortCircuitAnalysisResultsPage(nodeUuid, rootNetworkUuid, mode, type, filters, pageable); } else { - return getShortCircuitAnalysisResult(nodeUuid, mode, type); + return getShortCircuitAnalysisResult(nodeUuid, rootNetworkUuid, mode, type); } } - private String getShortCircuitAnalysisCsvResultResourcePath(UUID nodeUuid, ShortcircuitAnalysisType type) { - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, + private String getShortCircuitAnalysisCsvResultResourcePath(UUID nodeUuid, UUID rootNetworkUuid, ShortcircuitAnalysisType type) { + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, type == ShortcircuitAnalysisType.ALL_BUSES ? ComputationType.SHORT_CIRCUIT : ComputationType.SHORT_CIRCUIT_ONE_BUS); - if (resultUuidOpt.isEmpty()) { + if (resultUuid == null) { throw new StudyException(SHORT_CIRCUIT_ANALYSIS_NOT_FOUND); } String path = DELIMITER + SHORT_CIRCUIT_API_VERSION + "/results/{resultUuid}/csv"; - return UriComponentsBuilder.fromPath(path).buildAndExpand(resultUuidOpt.get()).toUriString(); + return UriComponentsBuilder.fromPath(path).buildAndExpand(resultUuid).toUriString(); } public byte[] getShortCircuitAnalysisCsvResultResource(URI resourcePath, String headersCsv) { @@ -165,14 +167,14 @@ public byte[] getShortCircuitAnalysisCsvResultResource(URI resourcePath, String } } - public byte[] getShortCircuitAnalysisCsvResult(UUID nodeUuid, ShortcircuitAnalysisType type, String headersCsv) { - String resultPath = getShortCircuitAnalysisCsvResultResourcePath(nodeUuid, type); + public byte[] getShortCircuitAnalysisCsvResult(UUID nodeUuid, UUID rootNetworkUuid, ShortcircuitAnalysisType type, String headersCsv) { + String resultPath = getShortCircuitAnalysisCsvResultResourcePath(nodeUuid, rootNetworkUuid, type); UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(shortCircuitServerBaseUri + resultPath); return getShortCircuitAnalysisCsvResultResource(builder.build().toUri(), headersCsv); } - public String getShortCircuitAnalysisResult(UUID nodeUuid, FaultResultsMode mode, ShortcircuitAnalysisType type) { - String resultPath = getShortCircuitAnalysisResultResourcePath(nodeUuid, type); + public String getShortCircuitAnalysisResult(UUID nodeUuid, UUID rootNetworkUuid, FaultResultsMode mode, ShortcircuitAnalysisType type) { + String resultPath = getShortCircuitAnalysisResultResourcePath(nodeUuid, rootNetworkUuid, type); if (resultPath == null) { return null; } @@ -182,8 +184,8 @@ public String getShortCircuitAnalysisResult(UUID nodeUuid, FaultResultsMode mode return getShortCircuitAnalysisResource(builder.build().toUri()); } - public String getShortCircuitAnalysisResultsPage(UUID nodeUuid, FaultResultsMode mode, ShortcircuitAnalysisType type, String filters, Pageable pageable) { - String resultsPath = getShortCircuitAnalysisResultsPageResourcePath(nodeUuid, type); + public String getShortCircuitAnalysisResultsPage(UUID nodeUuid, UUID rootNetworkUuid, FaultResultsMode mode, ShortcircuitAnalysisType type, String filters, Pageable pageable) { + String resultsPath = getShortCircuitAnalysisResultsPageResourcePath(nodeUuid, rootNetworkUuid, type); if (resultsPath == null) { return null; } @@ -200,8 +202,8 @@ public String getShortCircuitAnalysisResultsPage(UUID nodeUuid, FaultResultsMode return getShortCircuitAnalysisResource(builder.build().encode().toUri()); // need to encode because of filter JSON array } - public String getShortCircuitAnalysisStatus(UUID nodeUuid, ShortcircuitAnalysisType type) { - String resultPath = getShortCircuitAnalysisResultResourcePath(nodeUuid, type); + public String getShortCircuitAnalysisStatus(UUID nodeUuid, UUID rootNetworkUuid, ShortcircuitAnalysisType type) { + String resultPath = getShortCircuitAnalysisResultResourcePath(nodeUuid, rootNetworkUuid, type); if (resultPath == null) { return null; } @@ -224,25 +226,25 @@ public String getShortCircuitAnalysisResource(URI resourcePath) { return result; } - public void stopShortCircuitAnalysis(UUID studyUuid, UUID nodeUuid, String userId) { + public void stopShortCircuitAnalysis(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, String userId) { Objects.requireNonNull(studyUuid); Objects.requireNonNull(nodeUuid); Objects.requireNonNull(userId); - Optional resultUuidOpt = networkModificationTreeService.getComputationResultUuid(nodeUuid, ComputationType.SHORT_CIRCUIT); - if (resultUuidOpt.isEmpty()) { + UUID resultUuid = networkModificationTreeService.getComputationResultUuid(nodeUuid, rootNetworkUuid, ComputationType.SHORT_CIRCUIT); + if (resultUuid == null) { return; } String receiver; try { - receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid)), StandardCharsets.UTF_8); + receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(nodeUuid, rootNetworkUuid)), StandardCharsets.UTF_8); } catch (JsonProcessingException e) { throw new UncheckedIOException(e); } String path = UriComponentsBuilder .fromPath(DELIMITER + SHORT_CIRCUIT_API_VERSION + "/results/{resultUuid}/stop") - .queryParam(QUERY_PARAM_RECEIVER, receiver).buildAndExpand(resultUuidOpt.get()).toUriString(); + .queryParam(QUERY_PARAM_RECEIVER, receiver).buildAndExpand(resultUuid).toUriString(); HttpHeaders headers = new HttpHeaders(); headers.set(HEADER_USER_ID, userId); @@ -251,8 +253,8 @@ public void stopShortCircuitAnalysis(UUID studyUuid, UUID nodeUuid, String userI restTemplate.exchange(shortCircuitServerBaseUri + path, HttpMethod.PUT, new HttpEntity<>(headers), Void.class); } - private String getVariantId(UUID nodeUuid) { - return networkModificationTreeService.getVariantId(nodeUuid); + private String getVariantId(UUID nodeUuid, UUID rootNetworkUuid) { + return networkModificationTreeService.getVariantId(nodeUuid, rootNetworkUuid); } public void deleteShortCircuitAnalysisResult(UUID uuid) { @@ -279,9 +281,9 @@ public Integer getShortCircuitResultsCount() { return restTemplate.getForObject(shortCircuitServerBaseUri + path, Integer.class); } - public void assertShortCircuitAnalysisNotRunning(UUID nodeUuid) { - String scs = getShortCircuitAnalysisStatus(nodeUuid, ShortcircuitAnalysisType.ALL_BUSES); - String oneBusScs = getShortCircuitAnalysisStatus(nodeUuid, ShortcircuitAnalysisType.ONE_BUS); + public void assertShortCircuitAnalysisNotRunning(UUID nodeUuid, UUID rootNetworkUuid) { + String scs = getShortCircuitAnalysisStatus(nodeUuid, rootNetworkUuid, ShortcircuitAnalysisType.ALL_BUSES); + String oneBusScs = getShortCircuitAnalysisStatus(nodeUuid, rootNetworkUuid, ShortcircuitAnalysisType.ONE_BUS); if (ShortCircuitStatus.RUNNING.name().equals(scs) || ShortCircuitStatus.RUNNING.name().equals(oneBusScs)) { throw new StudyException(SHORT_CIRCUIT_ANALYSIS_RUNNING); } diff --git a/src/main/resources/db/changelog/changesets/changelog_20241008T170740Z.xml b/src/main/resources/db/changelog/changesets/changelog_20241008T170740Z.xml new file mode 100644 index 000000000..785d731af --- /dev/null +++ b/src/main/resources/db/changelog/changesets/changelog_20241008T170740Z.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/db/changelog/changesets/changelog_20241008T170741Z.xml b/src/main/resources/db/changelog/changesets/changelog_20241008T170741Z.xml new file mode 100644 index 000000000..71a0b5698 --- /dev/null +++ b/src/main/resources/db/changelog/changesets/changelog_20241008T170741Z.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/db/changelog/changesets/changelog_20241031T150610Z.xml b/src/main/resources/db/changelog/changesets/changelog_20241031T150610Z.xml new file mode 100644 index 000000000..498fce1d2 --- /dev/null +++ b/src/main/resources/db/changelog/changesets/changelog_20241031T150610Z.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/db/changelog/changesets/migrationDataRootNetworkH2.sql b/src/main/resources/db/changelog/changesets/migrationDataRootNetworkH2.sql new file mode 100644 index 000000000..5bcfab542 --- /dev/null +++ b/src/main/resources/db/changelog/changesets/migrationDataRootNetworkH2.sql @@ -0,0 +1,108 @@ +-- Migrating data into the root_network table, making sure we don't insert duplicates +INSERT INTO root_network ( + id, -- UUID (Primary Key) for the root_network table + case_format, -- Case format from the study + case_name, -- Case name from the study + case_uuid, -- UUID associated with the case from the study + network_id, -- Network ID from the study + network_uuid, -- UUID associated with the network from the study + report_uuid, -- UUID from the root_node_info (report) + study_uuid -- UUID associated with the study (foreign key to study table) +) +SELECT + random_uuid(), -- Generate a new unique UUID for the root_network row + s.case_format, -- Retrieve case_format from the study table + s.case_name, -- Retrieve case_name from the study table + s.case_uuid, -- Retrieve case_uuid from the study table + s.network_id, -- Retrieve network_id from the study table + s.network_uuid, -- Retrieve network_uuid from the study table + r.report_uuid, -- Retrieve report_uuid from root_node_info, linked by node + s.id AS study_uuid -- Use the study ID as study_uuid (foreign key) +FROM + study s -- Start from the study table + JOIN node n ON n.study_id = s.id -- Join with node table based on study_id + JOIN root_node_info r ON r.id_node = n.id_node -- Join with root_node_info based on node_id +WHERE + n.type = 'ROOT' + AND NOT EXISTS ( -- Prevent duplicates: check if a root_network entry with the same study_uuid already exists + SELECT 1 + FROM root_network tp + WHERE tp.study_uuid = s.id +); + +-- Migrating data into the root_network_node_info table, ensuring no duplicate rows are inserted +INSERT INTO root_network_node_info ( + id, -- UUID (Primary Key) for root_network_node_info + root_network_id, -- Foreign Key, linked to the root_network table + node_info_id, -- Foreign Key, linked to the network_modification_node_info table + dynamic_simulation_result_uuid, -- UUID for dynamic simulation result + loadflow_result_uuid, -- UUID for load flow result + global_build_status, -- Global build status + local_build_status, -- Local build status + non_evacuated_energy_result_uuid, -- UUID for non-evacuated energy result + one_bus_short_circuit_analysis_result_uuid, -- UUID for one bus short-circuit analysis result + security_analysis_result_uuid, -- UUID for security analysis result + sensitivity_analysis_result_uuid, -- UUID for sensitivity analysis result + short_circuit_analysis_result_uuid,-- UUID for short-circuit analysis result + state_estimation_result_uuid, -- UUID for state estimation result + variant_id, -- Variant ID for the network modification + voltage_init_result_uuid -- UUID for voltage initialization result +) +SELECT + random_uuid(), -- Generate a new unique UUID for each root_network_node_info row + t.id, -- Reference the id of the associated root_network + n.id_node, -- Reference the id of the associated network_modification_node_info + n.dynamic_simulation_result_uuid, -- Retrieve dynamic simulation result UUID from the table network_modification_node_info + n.loadflow_result_uuid, -- Retrieve load flow result UUID from the table network_modification_node_info + n.global_build_status, -- Retrieve global build status from the table network_modification_node_info + n.local_build_status, -- Retrieve local build status from the table network_modification_node_info + n.non_evacuated_energy_result_uuid, -- Retrieve non-evacuated energy result UUID from the table network_modification_node_info + n.one_bus_short_circuit_analysis_result_uuid, -- Retrieve one bus short-circuit analysis result UUID from the table network_modification_node_info + n.security_analysis_result_uuid, -- Retrieve security analysis result UUID from the table network_modification_node_info + n.sensitivity_analysis_result_uuid,-- Retrieve sensitivity analysis result UUID from the table network_modification_node_info + n.short_circuit_analysis_result_uuid,-- Retrieve short-circuit analysis result UUID from the table network_modification_node_info + n.state_estimation_result_uuid, -- Retrieve state estimation result UUID from the table network_modification_node_info + n.variant_id, -- Retrieve variant ID from the table network_modification_node_info + n.voltage_init_result_uuid -- Retrieve voltage initialization result UUID from the table network_modification_node_info +FROM + network_modification_node_info n -- Start from the network_modification_node_info table + JOIN node ne ON ne.id_node = n.id_node -- Join with the node table based on id_node + JOIN root_network t ON ne.study_id = t.study_uuid -- Join with root_network based on study_uuid +WHERE + NOT EXISTS ( -- Prevent duplicates: check if a root_network_node_info entry with the same root_network_id and node_info_id already exists + SELECT 1 + FROM root_network_node_info tpni + WHERE tpni.root_network_id = t.id + AND tpni.node_info_id = n.id_node + ); + +UPDATE modification_reports mr +SET root_network_node_info_entity_id = ( + SELECT tpn.id + FROM network_modification_node_info n + JOIN root_network_node_info tpn ON n.id_node = tpn.node_info_id + WHERE mr.network_modification_node_info_entity_id_node = n.id_node +) +WHERE mr.root_network_node_info_entity_id IS NULL + AND EXISTS ( + SELECT 1 + FROM network_modification_node_info n + JOIN root_network_node_info tpn ON n.id_node = tpn.node_info_id + WHERE mr.network_modification_node_info_entity_id_node = n.id_node +); + +UPDATE computation_reports cr +SET root_network_node_info_entity_id = ( + SELECT tpn.id + FROM network_modification_node_info n + JOIN root_network_node_info tpn ON n.id_node = tpn.node_info_id + WHERE cr.network_modification_node_info_entity_id_node = n.id_node +) +WHERE cr.root_network_node_info_entity_id IS NULL + AND EXISTS ( + SELECT 1 + FROM network_modification_node_info n + JOIN root_network_node_info tpn ON n.id_node = tpn.node_info_id + WHERE cr.network_modification_node_info_entity_id_node = n.id_node +); + diff --git a/src/main/resources/db/changelog/changesets/migrationDataRootNetworkPostgres.sql b/src/main/resources/db/changelog/changesets/migrationDataRootNetworkPostgres.sql new file mode 100644 index 000000000..792ed6670 --- /dev/null +++ b/src/main/resources/db/changelog/changesets/migrationDataRootNetworkPostgres.sql @@ -0,0 +1,96 @@ +-- Migrating data into the root_network table, making sure we don't insert duplicates +INSERT INTO root_network ( + id, -- UUID (Primary Key) for the root_network table + case_format, -- Case format from the study + case_name, -- Case name from the study + case_uuid, -- UUID associated with the case from the study + network_id, -- Network ID from the study + network_uuid, -- UUID associated with the network from the study + report_uuid, -- UUID from the root_node_info (report) + study_uuid -- UUID associated with the study (foreign key to study table) +) +SELECT + gen_random_uuid(), -- Generate a new unique UUID for the root_network row + s.case_format, -- Retrieve case_format from the study table + s.case_name, -- Retrieve case_name from the study table + s.case_uuid, -- Retrieve case_uuid from the study table + s.network_id, -- Retrieve network_id from the study table + s.network_uuid, -- Retrieve network_uuid from the study table + r.report_uuid, -- Retrieve report_uuid from root_node_info, linked by node + s.id AS study_uuid -- Use the study ID as study_uuid (foreign key) +FROM + study s -- Start from the study table + JOIN node n ON n.study_id = s.id -- Join with node table based on study_id + JOIN root_node_info r ON r.id_node = n.id_node -- Join with root_node_info based on node_id +WHERE + n.type = 'ROOT' + AND NOT EXISTS ( -- Prevent duplicates: check if a root_network entry with the same study_uuid already exists + SELECT 1 + FROM root_network tp + WHERE tp.study_uuid = s.id +); + +-- Migrating data into the root_network_node_info table, ensuring no duplicate rows are inserted +INSERT INTO root_network_node_info ( + id, -- UUID (Primary Key) for root_network_node_info + root_network_id, -- Foreign Key, linked to the root_network table + node_info_id, -- Foreign Key, linked to the network_modification_node_info table + dynamic_simulation_result_uuid, -- UUID for dynamic simulation result + loadflow_result_uuid, -- UUID for load flow result + global_build_status, -- Global build status + local_build_status, -- Local build status + non_evacuated_energy_result_uuid, -- UUID for non-evacuated energy result + one_bus_short_circuit_analysis_result_uuid, -- UUID for one bus short-circuit analysis result + security_analysis_result_uuid, -- UUID for security analysis result + sensitivity_analysis_result_uuid, -- UUID for sensitivity analysis result + short_circuit_analysis_result_uuid,-- UUID for short-circuit analysis result + state_estimation_result_uuid, -- UUID for state estimation result + variant_id, -- Variant ID for the network modification + voltage_init_result_uuid -- UUID for voltage initialization result +) +SELECT + gen_random_uuid(), -- Generate a new unique UUID for each root_network_node_info row + t.id, -- Reference the id of the associated root_network + n.id_node, -- Reference the id of the associated network_modification_node_info + n.dynamic_simulation_result_uuid, -- Retrieve dynamic simulation result UUID from the table network_modification_node_info + n.loadflow_result_uuid, -- Retrieve load flow result UUID from the table network_modification_node_info + n.global_build_status, -- Retrieve global build status from the table network_modification_node_info + n.local_build_status, -- Retrieve local build status from the table network_modification_node_info + n.non_evacuated_energy_result_uuid, -- Retrieve non-evacuated energy result UUID from the table network_modification_node_info + n.one_bus_short_circuit_analysis_result_uuid, -- Retrieve one bus short-circuit analysis result UUID from the table network_modification_node_info + n.security_analysis_result_uuid, -- Retrieve security analysis result UUID from the table network_modification_node_info + n.sensitivity_analysis_result_uuid,-- Retrieve sensitivity analysis result UUID from the table network_modification_node_info + n.short_circuit_analysis_result_uuid,-- Retrieve short-circuit analysis result UUID from the table network_modification_node_info + n.state_estimation_result_uuid, -- Retrieve state estimation result UUID from the table network_modification_node_info + n.variant_id, -- Retrieve variant ID from the table network_modification_node_info + n.voltage_init_result_uuid -- Retrieve voltage initialization result UUID from the table network_modification_node_info +FROM + network_modification_node_info n -- Start from the network_modification_node_info table + JOIN node ne ON ne.id_node = n.id_node -- Join with the node table based on id_node + JOIN root_network t ON ne.study_id = t.study_uuid -- Join with root_network based on study_uuid +WHERE + NOT EXISTS ( -- Prevent duplicates: check if a root_network_node_info entry with the same root_network_id and node_info_id already exists + SELECT 1 + FROM root_network_node_info tpni + WHERE tpni.root_network_id = t.id + AND tpni.node_info_id = n.id_node + ); + + + +-- Update existing modification_reports to set root_network_node_info_entity_id +UPDATE modification_reports mr +SET root_network_node_info_entity_id = tpn.id +FROM network_modification_node_info n + JOIN root_network_node_info tpn ON n.id_node = tpn.node_info_id +WHERE mr.network_modification_node_info_entity_id_node = n.id_node -- foreign key column 'network_modification_node_info_entity_id_node' in modification_reports +AND mr.root_network_node_info_entity_id IS NULL; -- Only update if the column is NULL + + +-- Update existing computation_reports to set root_network_node_info_entity_id +UPDATE computation_reports cr +SET root_network_node_info_entity_id = tpn.id +FROM network_modification_node_info n + JOIN root_network_node_info tpn ON n.id_node = tpn.node_info_id +WHERE cr.network_modification_node_info_entity_id_node = n.id_node -- a foreign key column 'network_modification_node_info_entity_id_node' in computation_reports +AND cr.root_network_node_info_entity_id IS NULL; -- Only update if the column is NULL diff --git a/src/main/resources/db/changelog/db.changelog-master.yaml b/src/main/resources/db/changelog/db.changelog-master.yaml index b11e22124..2de91ea8e 100644 --- a/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/src/main/resources/db/changelog/db.changelog-master.yaml @@ -246,4 +246,13 @@ databaseChangeLog: relativeToChangelogFile: true - include: file: changesets/changelog_20241009T223735Z.xml + relativeToChangelogFile: true + - include: + file: changesets/changelog_20241008T170740Z.xml + relativeToChangelogFile: true + - include: + file: changesets/changelog_20241008T170741Z.xml + relativeToChangelogFile: true + - include: + file: changesets/changelog_20241031T150610Z.xml relativeToChangelogFile: true \ No newline at end of file diff --git a/src/test/java/org/gridsuite/study/server/CaseTest.java b/src/test/java/org/gridsuite/study/server/CaseTest.java index a1d2b3e4a..51a6693d1 100644 --- a/src/test/java/org/gridsuite/study/server/CaseTest.java +++ b/src/test/java/org/gridsuite/study/server/CaseTest.java @@ -111,9 +111,9 @@ void getCaseName() throws Exception { } private StudyEntity insertDummyStudy(UUID networkUuid, UUID caseUuid, String caseName) { - StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, caseUuid, caseName, ""); + StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, caseUuid, caseName, "", null); var study = studyRepository.save(studyEntity); - networkModificationTreeService.createRoot(studyEntity, null); + networkModificationTreeService.createRoot(studyEntity); return study; } diff --git a/src/test/java/org/gridsuite/study/server/EquipmentInfosServiceTests.java b/src/test/java/org/gridsuite/study/server/EquipmentInfosServiceTests.java index 862895d6c..44a985cfb 100644 --- a/src/test/java/org/gridsuite/study/server/EquipmentInfosServiceTests.java +++ b/src/test/java/org/gridsuite/study/server/EquipmentInfosServiceTests.java @@ -27,6 +27,7 @@ import org.gridsuite.study.server.service.NetworkModificationTreeService; import org.gridsuite.study.server.service.NetworkService; import org.gridsuite.study.server.service.StudyService; +import org.gridsuite.study.server.service.RootNetworkService; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -69,6 +70,7 @@ class EquipmentInfosServiceTests implements WithAssertions { private static final UUID NETWORK_UUID_2 = UUID.fromString("8c73b846-5dbe-4ac8-a9c9-8422fda261bb"); private static final UUID NODE_UUID = UUID.fromString("12345678-8cf0-11bd-b23e-10b96e4ef00d"); + private static final UUID ROOTNETWORK_UUID = UUID.fromString("23456789-8cf0-11bd-b23e-10b96e4ef00d"); @Autowired private EquipmentInfosService equipmentInfosService; @@ -79,13 +81,17 @@ class EquipmentInfosServiceTests implements WithAssertions { @MockBean private NetworkModificationTreeService networkModificationTreeService; + @MockBean + private RootNetworkService rootNetworkService; + @Autowired private StudyService studyService; @BeforeEach void setup() { - when(networkStoreService.getNetworkUuid(NETWORK_UUID)).thenReturn(NETWORK_UUID); - when(networkModificationTreeService.getVariantId(NODE_UUID)).thenReturn(VariantManagerConstants.INITIAL_VARIANT_ID); +// when(networkStoreService.getNetworkUuid(NETWORK_UUID)).thenReturn(NETWORK_UUID); + when(networkModificationTreeService.getVariantId(NODE_UUID, ROOTNETWORK_UUID)).thenReturn(VariantManagerConstants.INITIAL_VARIANT_ID); + when(rootNetworkService.getNetworkUuid(ROOTNETWORK_UUID)).thenReturn(NETWORK_UUID); } @AfterEach @@ -351,7 +357,7 @@ private static String createEquipmentName(String name) { } private void testNameFullAscii(String pat) { - assertEquals(1, studyService.searchEquipments(NETWORK_UUID, NODE_UUID, pat, EquipmentInfosService.FieldSelector.NAME, null, false).size()); + assertEquals(1, studyService.searchEquipments(NODE_UUID, ROOTNETWORK_UUID, pat, EquipmentInfosService.FieldSelector.NAME, null, false).size()); } private void testNameFullAsciis() { diff --git a/src/test/java/org/gridsuite/study/server/FilterServiceTest.java b/src/test/java/org/gridsuite/study/server/FilterServiceTest.java index 099ebbf2a..0e8d78bce 100644 --- a/src/test/java/org/gridsuite/study/server/FilterServiceTest.java +++ b/src/test/java/org/gridsuite/study/server/FilterServiceTest.java @@ -99,9 +99,9 @@ void tearDown() { } private StudyEntity insertDummyStudy(UUID networkUuid, UUID caseUuid) { - StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, caseUuid, "", null, null, null, null, null); + StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, "netId", caseUuid, "", "", null, null, null, null, null, null); var study = studyRepository.save(studyEntity); - networkModificationTreeService.createRoot(studyEntity, null); + networkModificationTreeService.createRoot(studyEntity); return study; } diff --git a/src/test/java/org/gridsuite/study/server/LoadFlowTest.java b/src/test/java/org/gridsuite/study/server/LoadFlowTest.java index 2ff4d0247..fbf043a69 100644 --- a/src/test/java/org/gridsuite/study/server/LoadFlowTest.java +++ b/src/test/java/org/gridsuite/study/server/LoadFlowTest.java @@ -31,7 +31,7 @@ import org.gridsuite.study.server.notification.NotificationService; import org.gridsuite.study.server.repository.StudyEntity; import org.gridsuite.study.server.repository.StudyRepository; -import org.gridsuite.study.server.repository.networkmodificationtree.NetworkModificationNodeInfoRepository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkNodeInfoRepository; import org.gridsuite.study.server.repository.nonevacuatedenergy.NonEvacuatedEnergyParametersEntity; import org.gridsuite.study.server.service.*; import org.gridsuite.study.server.utils.TestUtils; @@ -164,7 +164,7 @@ class LoadFlowTest { @Autowired private ReportService reportService; @Autowired - private NetworkModificationNodeInfoRepository networkModificationNodeInfoRepository; + private RootNetworkNodeInfoRepository rootNetworkNodeInfoRepository; @BeforeEach void setup(final MockWebServer server) throws Exception { @@ -240,12 +240,12 @@ public MockResponse dispatch(RecordedRequest request) { if (path.matches("/v1/networks/" + NETWORK_UUID_STRING + "/run-and-save\\?receiver=.*&reportUuid=.*&reporterId=.*&variantId=" + VARIANT_ID_2 + ".*")) { input.send(MessageBuilder.withPayload("") .setHeader("resultUuid", LOADFLOW_RESULT_UUID) - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .build(), LOADFLOW_RESULT_DESTINATION); return new MockResponse(200, Headers.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE), loadFlowResultUuidStr); } else if (path.matches("/v1/networks/" + NETWORK_UUID_STRING + "/run-and-save\\?receiver=.*&reportUuid=.*&reporterId=.*&variantId=" + VARIANT_ID)) { input.send(MessageBuilder.withPayload("") - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .build(), LOADFLOW_FAILED_DESTINATION); return new MockResponse(200, Headers.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE), loadFlowErrorResultUuidStr); } else if (path.matches("/v1/results/" + LOADFLOW_RESULT_UUID)) { @@ -269,7 +269,7 @@ public MockResponse dispatch(RecordedRequest request) { String resultUuid = path.matches(".*variantId=" + VARIANT_ID_2 + ".*") ? LOADFLOW_OTHER_NODE_RESULT_UUID : LOADFLOW_RESULT_UUID; input.send(MessageBuilder.withPayload("") .setHeader("resultUuid", resultUuid) - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .build(), LOADFLOW_STOPPED_DESTINATION); return new MockResponse(200); } else if (path.matches("/v1/results")) { @@ -511,22 +511,23 @@ void testResetUuidResultWhenLFFailed() throws Exception { StudyEntity studyEntity = insertDummyStudy(UUID.randomUUID(), UUID.randomUUID(), LOADFLOW_PARAMETERS_UUID); RootNode rootNode = networkModificationTreeService.getStudyTree(studyEntity.getId()); NetworkModificationNode modificationNode = createNetworkModificationNode(studyEntity.getId(), rootNode.getId(), UUID.randomUUID(), VARIANT_ID, "node 1"); - String resultUuidJson = objectMapper.writeValueAsString(new NodeReceiver(modificationNode.getId())); + UUID rootNetworkUuid = studyEntity.getFirstRootNetwork().getId(); + String resultUuidJson = objectMapper.writeValueAsString(new NodeReceiver(modificationNode.getId(), rootNetworkUuid)); // Set an uuid result in the database - networkModificationTreeService.updateComputationResultUuid(modificationNode.getId(), resultUuid, LOAD_FLOW); - assertTrue(networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), LOAD_FLOW).isPresent()); - assertEquals(resultUuid, networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), LOAD_FLOW).get()); + networkModificationTreeService.updateComputationResultUuid(modificationNode.getId(), rootNetworkUuid, resultUuid, LOAD_FLOW); + assertNotNull(networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), rootNetworkUuid, LOAD_FLOW)); + assertEquals(resultUuid, networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), rootNetworkUuid, LOAD_FLOW)); StudyService studyService = Mockito.mock(StudyService.class); doAnswer(invocation -> { input.send(MessageBuilder.withPayload("").setHeader(HEADER_RECEIVER, resultUuidJson).build(), LOADFLOW_FAILED_DESTINATION); return resultUuid; - }).when(studyService).runLoadFlow(any(), any(), any(), any()); - studyService.runLoadFlow(studyEntity.getId(), modificationNode.getId(), "", null); + }).when(studyService).runLoadFlow(any(), any(), any(), any(), any()); + studyService.runLoadFlow(studyEntity.getId(), modificationNode.getId(), rootNetworkUuid, "", null); // Test reset uuid result in the database - assertTrue(networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), LOAD_FLOW).isEmpty()); + assertNull(networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), rootNetworkUuid, LOAD_FLOW)); Message message = output.receive(TIMEOUT, STUDY_UPDATE_DESTINATION); assertEquals(studyEntity.getId(), message.getHeaders().get(NotificationService.HEADER_STUDY_UUID)); @@ -558,7 +559,7 @@ private void testResultCount(final MockWebServer server) throws Exception { } private void testDeleteResults(int expectedInitialResultCount, final MockWebServer server) throws Exception { - assertEquals(expectedInitialResultCount, networkModificationNodeInfoRepository.findAllByLoadFlowResultUuidNotNull().size()); + assertEquals(expectedInitialResultCount, rootNetworkNodeInfoRepository.findAllByLoadFlowResultUuidNotNull().size()); mockMvc.perform(delete("/v1/supervision/computation/results") .queryParam("type", LOAD_FLOW.toString()) .queryParam("dryRun", "false")) @@ -567,7 +568,7 @@ private void testDeleteResults(int expectedInitialResultCount, final MockWebServ var requests = TestUtils.getRequestsDone(2, server); assertTrue(requests.contains("/v1/results")); assertTrue(requests.stream().anyMatch(r -> r.matches("/v1/reports"))); - assertEquals(0, networkModificationNodeInfoRepository.findAllByLoadFlowResultUuidNotNull().size()); + assertEquals(0, rootNetworkNodeInfoRepository.findAllByLoadFlowResultUuidNotNull().size()); } @Test @@ -760,11 +761,11 @@ void testLoadFlowParameters(final MockWebServer server) throws Exception { private StudyEntity insertDummyStudy(UUID networkUuid, UUID caseUuid, UUID loadFlowParametersUuid) { NonEvacuatedEnergyParametersEntity defaultNonEvacuatedEnergyParametersEntity = NonEvacuatedEnergyService.toEntity(NonEvacuatedEnergyService.getDefaultNonEvacuatedEnergyParametersInfos()); - StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, caseUuid, "", + StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, "netId", caseUuid, "", "", null, loadFlowParametersUuid, null, null, null, defaultNonEvacuatedEnergyParametersEntity); var study = studyRepository.save(studyEntity); - networkModificationTreeService.createRoot(studyEntity, null); + networkModificationTreeService.createRoot(studyEntity); return study; } diff --git a/src/test/java/org/gridsuite/study/server/NetworkMapTest.java b/src/test/java/org/gridsuite/study/server/NetworkMapTest.java index b5f640491..cfa3c942c 100644 --- a/src/test/java/org/gridsuite/study/server/NetworkMapTest.java +++ b/src/test/java/org/gridsuite/study/server/NetworkMapTest.java @@ -491,9 +491,9 @@ void testGetBusesOrBusbarSections(final MockWebServer server) throws Exception { } private StudyEntity insertDummyStudy(UUID networkUuid, UUID caseUuid) { - StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, caseUuid, "", LOADFLOW_PARAMETERS_UUID, null, null, null, null); + StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, "netId", caseUuid, "", "", null, LOADFLOW_PARAMETERS_UUID, null, null, null, null); var study = studyRepository.save(studyEntity); - networkModificationTreeService.createRoot(studyEntity, null); + networkModificationTreeService.createRoot(studyEntity); return study; } diff --git a/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java b/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java index cafc06e86..1444235ac 100644 --- a/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java +++ b/src/test/java/org/gridsuite/study/server/NetworkModificationTest.java @@ -370,6 +370,7 @@ public MockResponse dispatch(RecordedRequest request) { @Test void testBuildFailed() throws Exception { StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_2_STRING), CASE_2_UUID, "UCTE"); + UUID rootNetworkUuid = studyEntity.getFirstRootNetwork().getId(); UUID studyUuid = studyEntity.getId(); UUID rootNodeUuid = getRootNode(studyUuid).getId(); @@ -377,25 +378,27 @@ void testBuildFailed() throws Exception { NetworkModificationNode modificationNode = createNetworkModificationNode(studyUuid, rootNodeUuid, modificationGroupUuid1, "variant_1", "node 1", USER_ID); - testBuildFailedWithNodeUuid(studyUuid, modificationNode.getId()); + testBuildFailedWithNodeUuid(studyUuid, modificationNode.getId(), rootNetworkUuid); } @Test void testBuildError() throws Exception { StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_3_STRING), CASE_3_UUID, "UCTE"); + UUID rootNetworkUuid = studyEntity.getFirstRootNetwork().getId(); UUID studyUuid = studyEntity.getId(); UUID rootNodeUuid = getRootNode(studyUuid).getId(); UUID modificationGroupUuid1 = UUID.randomUUID(); NetworkModificationNode modificationNode = createNetworkModificationNode(studyUuid, rootNodeUuid, modificationGroupUuid1, "variant_1", "node 1", USER_ID); - testBuildErrorWithNodeUuid(studyUuid, modificationNode.getId()); + testBuildErrorWithNodeUuid(studyUuid, modificationNode.getId(), rootNetworkUuid); } @Test void testBuildQuotaExceeded() throws Exception { String userId = USER_ID_QUOTA_EXCEEDED; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); + UUID rootNetworkUuid = studyEntity.getFirstRootNetwork().getId(); UUID studyNameUserIdUuid = studyEntity.getId(); UUID rootNodeUuid = getRootNode(studyNameUserIdUuid).getId(); UUID modificationGroupUuid1 = UUID.randomUUID(); @@ -406,7 +409,7 @@ void testBuildQuotaExceeded() throws Exception { modificationNode1.getId(), modificationGroupUuid2, "variant_2", "node 2", userId); // build modificationNode1: ok - testBuildWithNodeUuid(studyNameUserIdUuid, modificationNode1.getId(), userId, userProfileQuotaExceededStubId); + testBuildWithNodeUuid(studyNameUserIdUuid, modificationNode1.getId(), rootNetworkUuid, userId, userProfileQuotaExceededStubId); // build modificationNode2: cannot be done cause quota is 1 build max (err 403) MvcResult result = mockMvc.perform(post("/v1/studies/{studyUuid}/nodes/{nodeUuid}/build", studyNameUserIdUuid, modificationNode2.getId()) @@ -422,6 +425,7 @@ void testBuildQuotaExceeded() throws Exception { void testBuildNoQuotaInProfile() throws Exception { String userId = USER_ID_NO_QUOTA; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); + UUID rootNetworkUuid = studyEntity.getFirstRootNetwork().getId(); UUID studyNameUserIdUuid = studyEntity.getId(); UUID rootNodeUuid = getRootNode(studyNameUserIdUuid).getId(); UUID modificationGroupUuid1 = UUID.randomUUID(); @@ -429,13 +433,14 @@ void testBuildNoQuotaInProfile() throws Exception { modificationGroupUuid1, "variant_1", "node 1", userId); // build modificationNode1: ok - testBuildWithNodeUuid(studyNameUserIdUuid, modificationNode1.getId(), userId, userProfileNoQuotaStubId); + testBuildWithNodeUuid(studyNameUserIdUuid, modificationNode1.getId(), rootNetworkUuid, userId, userProfileNoQuotaStubId); } @Test void testBuildNoProfile() throws Exception { String userId = USER_ID_NO_PROFILE; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); + UUID rootNetworkUuid = studyEntity.getFirstRootNetwork().getId(); UUID studyNameUserIdUuid = studyEntity.getId(); UUID rootNodeUuid = getRootNode(studyNameUserIdUuid).getId(); UUID modificationGroupUuid1 = UUID.randomUUID(); @@ -443,13 +448,14 @@ void testBuildNoProfile() throws Exception { modificationGroupUuid1, "variant_1", "node 1", userId); // build modificationNode1: ok - testBuildWithNodeUuid(studyNameUserIdUuid, modificationNode1.getId(), userId, userNoProfileStubId); + testBuildWithNodeUuid(studyNameUserIdUuid, modificationNode1.getId(), rootNetworkUuid, userId, userNoProfileStubId); } @Test void testBuild() throws Exception { String userId = USER_ID; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); + UUID rootNetworkUuid = studyEntity.getFirstRootNetwork().getId(); UUID studyNameUserIdUuid = studyEntity.getId(); UUID rootNodeUuid = getRootNode(studyNameUserIdUuid).getId(); UUID modificationGroupUuid1 = UUID.randomUUID(); @@ -482,7 +488,7 @@ void testBuild() throws Exception { modificationNode5 */ - BuildInfos buildInfos = networkModificationTreeService.getBuildInfos(modificationNode5.getId()); + BuildInfos buildInfos = networkModificationTreeService.getBuildInfos(modificationNode5.getId(), rootNetworkUuid); assertNull(buildInfos.getOriginVariantId()); // previous built node is root node assertEquals("variant_5", buildInfos.getDestinationVariantId()); assertEquals(List.of(modificationGroupUuid1, modificationGroupUuid2, modificationGroupUuid3, modificationGroupUuid4, modificationGroupUuid5), buildInfos.getModificationGroupUuids()); @@ -492,7 +498,7 @@ void testBuild() throws Exception { checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); output.receive(TIMEOUT, STUDY_UPDATE_DESTINATION); - buildInfos = networkModificationTreeService.getBuildInfos(modificationNode4.getId()); + buildInfos = networkModificationTreeService.getBuildInfos(modificationNode4.getId(), rootNetworkUuid); assertEquals("variant_3", buildInfos.getOriginVariantId()); // variant to clone is variant associated to node // modificationNode3 assertEquals("variant_4", buildInfos.getDestinationVariantId()); @@ -512,11 +518,11 @@ void testBuild() throws Exception { output.receive(TIMEOUT, STUDY_UPDATE_DESTINATION); // build modificationNode2 and stop build - testBuildAndStopWithNodeUuid(studyNameUserIdUuid, modificationNode2.getId(), userId, userProfileQuotaStubId); + testBuildAndStopWithNodeUuid(studyNameUserIdUuid, modificationNode2.getId(), rootNetworkUuid, userId, userProfileQuotaStubId); - assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode3.getId()).getGlobalBuildStatus()); - assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode4.getId()).getGlobalBuildStatus()); - assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode5.getId()).getGlobalBuildStatus()); + assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode3.getId(), rootNetworkUuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode4.getId(), rootNetworkUuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode5.getId(), rootNetworkUuid).getGlobalBuildStatus()); modificationNode3.setNodeBuildStatus(NodeBuildStatus.from(BuildStatus.NOT_BUILT)); // mark node modificationNode3 as built networkModificationTreeService.updateNode(studyNameUserIdUuid, modificationNode3, userId); @@ -524,15 +530,16 @@ void testBuild() throws Exception { output.receive(TIMEOUT, STUDY_UPDATE_DESTINATION); // build modificationNode3 and stop build - testBuildAndStopWithNodeUuid(studyNameUserIdUuid, modificationNode3.getId(), userId, userProfileQuotaStubId); + testBuildAndStopWithNodeUuid(studyNameUserIdUuid, modificationNode3.getId(), rootNetworkUuid, userId, userProfileQuotaStubId); - assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode4.getId()).getGlobalBuildStatus()); - assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode5.getId()).getGlobalBuildStatus()); + assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode4.getId(), rootNetworkUuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode5.getId(), rootNetworkUuid).getGlobalBuildStatus()); } @Test void testLocalBuildValue() throws Exception { StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); + UUID rootNetworkUuid = studyEntity.getFirstRootNetwork().getId(); UUID studyNameUserIdUuid = studyEntity.getId(); UUID rootNodeUuid = getRootNode(studyNameUserIdUuid).getId(); String userId = "userId"; @@ -575,7 +582,7 @@ void testLocalBuildValue() throws Exception { checkNodesBuildStatusUpdatedMessageReceived(studyNameUserIdUuid, List.of(modificationNodeUuid)); checkUpdateModelsStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); - assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(modificationNodeUuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(modificationNodeUuid, rootNetworkUuid).getGlobalBuildStatus()); wireMockUtils.verifyNetworkModificationPost(stubId, jsonCreateLoadInfos, NETWORK_UUID_STRING); // Build second node is OK @@ -593,12 +600,12 @@ void testLocalBuildValue() throws Exception { checkNodesBuildStatusUpdatedMessageReceived(studyNameUserIdUuid, List.of(modificationNode2Uuid)); checkUpdateModelsStatusMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); - assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(modificationNode2Uuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(modificationNode2Uuid, rootNetworkUuid).getGlobalBuildStatus()); wireMockUtils.verifyNetworkModificationPost(stubId, jsonCreateLoadInfos, NETWORK_UUID_STRING); //Build modification node 2, local status should be BUILT and computed one should be BUILT_WITH_ERRORS - assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode2Uuid).getLocalBuildStatus()); - assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(modificationNode2Uuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode2Uuid, rootNetworkUuid).getLocalBuildStatus()); + assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(modificationNode2Uuid, rootNetworkUuid).getGlobalBuildStatus()); } @Test @@ -609,6 +616,7 @@ void testNetworkModificationSwitch(final MockWebServer server) throws Exception String userId = "userId"; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); + UUID rootNetworkUuid = studyEntity.getFirstRootNetwork().getId(); UUID studyNameUserIdUuid = studyEntity.getId(); UUID rootNodeUuid = getRootNode(studyNameUserIdUuid).getId(); NetworkModificationNode modificationNode1 = createNetworkModificationNode(studyNameUserIdUuid, rootNodeUuid, @@ -698,10 +706,10 @@ void testNetworkModificationSwitch(final MockWebServer server) throws Exception assertTrue(requests.stream().anyMatch(r -> r.getPath().matches("/v1/reports"))); // modificationNode2 is still built - assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode1Uuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode1Uuid, rootNetworkUuid).getGlobalBuildStatus()); // modificationNode2 is now invalid - assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode2Uuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode2Uuid, rootNetworkUuid).getGlobalBuildStatus()); } @Test @@ -1100,9 +1108,7 @@ void deleteModificationRequest() throws Exception { mockMvc.perform(delete(URI_NETWORK_MODIF, studyUuid1, modificationNode.getId()) .queryParam("uuids", node3.getId().toString()) .header(USER_ID_HEADER, userId)) - .andExpect(status().isForbidden()); - checkEquipmentDeletingMessagesReceived(studyUuid1, modificationNode.getId()); - checkEquipmentDeletingFinishedMessagesReceived(studyUuid1, modificationNode.getId()); + .andExpect(status().isNotFound()); UUID modificationUuid = UUID.randomUUID(); mockMvc.perform(delete(URI_NETWORK_MODIF, studyUuid, modificationNode.getId()) @@ -2011,9 +2017,7 @@ void testReorderModificationErrorCase() throws Exception { mockMvc.perform(put("/v1/studies/{studyUuid}/nodes/{nodeUuid}/network-modification/{modificationID}?beforeUuid={modificationID2}", studyNameUserIdUuid1, modificationNodeUuid, modification1, modification2).header(USER_ID_HEADER, "userId")) - .andExpect(status().isForbidden()); - checkEquipmentUpdatingMessagesReceived(studyNameUserIdUuid1, modificationNodeUuid); - checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid1, modificationNodeUuid); + .andExpect(status().isNotFound()); } @Test @@ -2310,6 +2314,7 @@ void testDeleteEquipment() throws Exception { void testNodesInvalidation(final MockWebServer server) throws Exception { String userId = "userId"; StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); + UUID rootNetworkUuid = studyEntity.getFirstRootNetwork().getId(); UUID studyNameUserIdUuid = studyEntity.getId(); UUID rootNodeUuid = getRootNode(studyNameUserIdUuid).getId(); NetworkModificationNode modificationNode1 = createNetworkModificationNode(studyNameUserIdUuid, rootNodeUuid, UUID.randomUUID(), VARIANT_ID, "node 1", BuildStatus.BUILT, userId); @@ -2377,7 +2382,7 @@ void testNodesInvalidation(final MockWebServer server) throws Exception { checkUpdateModelsStatusMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); - assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode3Uuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNode3Uuid, rootNetworkUuid).getGlobalBuildStatus()); wireMockUtils.verifyNetworkModificationPost(stubUuid, jsonCreateLoadInfos, NETWORK_UUID_STRING); requests = TestUtils.getRequestsWithBodyDone(1, server); @@ -2452,6 +2457,7 @@ void testRemoveLoadFlowComputationReport(final MockWebServer server) throws Exce @Test void testUpdateOfBuildStatus() throws Exception { StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID, "UCTE"); + UUID rootNetworkUuid = studyEntity.getFirstRootNetwork().getId(); UUID studyNameUserIdUuid = studyEntity.getId(); UUID rootNodeUuid = getRootNode(studyNameUserIdUuid).getId(); String userId = "userId"; @@ -2473,7 +2479,7 @@ void testUpdateOfBuildStatus() throws Exception { checkUpdateModelsStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkElementUpdatedMessageSent(studyNameUserIdUuid, userId); - assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNodeUuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNodeUuid, rootNetworkUuid).getGlobalBuildStatus()); wireMockUtils.verifyNetworkModificationPostWithVariant(stubId, jsonCreateLoadInfos, NETWORK_UUID_STRING, VARIANT_ID); // Mark the node status as built @@ -2498,7 +2504,7 @@ void testUpdateOfBuildStatus() throws Exception { checkNodesBuildStatusUpdatedMessageReceived(studyNameUserIdUuid, List.of(modificationNodeUuid)); checkUpdateModelsStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); - assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNodeUuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(modificationNodeUuid, rootNetworkUuid).getGlobalBuildStatus()); wireMockUtils.verifyNetworkModificationPostWithVariant(stubId, jsonCreateLoadInfos, NETWORK_UUID_STRING, VARIANT_ID); // Built with warnings @@ -2515,7 +2521,7 @@ void testUpdateOfBuildStatus() throws Exception { checkNodesBuildStatusUpdatedMessageReceived(studyNameUserIdUuid, List.of(modificationNodeUuid)); checkUpdateModelsStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); - assertEquals(BuildStatus.BUILT_WITH_WARNING, networkModificationTreeService.getNodeBuildStatus(modificationNodeUuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.BUILT_WITH_WARNING, networkModificationTreeService.getNodeBuildStatus(modificationNodeUuid, rootNetworkUuid).getGlobalBuildStatus()); wireMockUtils.verifyNetworkModificationPost(stubId, jsonCreateLoadInfos, NETWORK_UUID_STRING); // Built with errors @@ -2532,11 +2538,11 @@ void testUpdateOfBuildStatus() throws Exception { checkNodesBuildStatusUpdatedMessageReceived(studyNameUserIdUuid, List.of(modificationNodeUuid)); checkUpdateModelsStatusMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); checkEquipmentUpdatingFinishedMessagesReceived(studyNameUserIdUuid, modificationNodeUuid); - assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(modificationNodeUuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(modificationNodeUuid, rootNetworkUuid).getGlobalBuildStatus()); wireMockUtils.verifyNetworkModificationPost(stubId, jsonCreateLoadInfos, NETWORK_UUID_STRING); } - private void testBuildWithNodeUuid(UUID studyUuid, UUID nodeUuid, String userId, UUID profileStubId) throws Exception { + private void testBuildWithNodeUuid(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, String userId, UUID profileStubId) throws Exception { // build node mockMvc.perform(post("/v1/studies/{studyUuid}/nodes/{nodeUuid}/build", studyUuid, nodeUuid) .header(USER_ID_HEADER, userId)) @@ -2561,10 +2567,10 @@ private void testBuildWithNodeUuid(UUID studyUuid, UUID nodeUuid, String userId, wireMockUtils.verifyGetRequest(profileStubId, "/v1/users/" + userId + "/profile/max-builds", Map.of()); wireMockUtils.verifyPostRequest(buildOkStubId, "/v1/networks/" + NETWORK_UUID_STRING + "/build", Map.of(QUERY_PARAM_RECEIVER, WireMock.matching(".*"))); - assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(nodeUuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(nodeUuid, rootNetworkUuid).getGlobalBuildStatus()); } - private void testBuildAndStopWithNodeUuid(UUID studyUuid, UUID nodeUuid, String userId, UUID profileStubId) throws Exception { + private void testBuildAndStopWithNodeUuid(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid, String userId, UUID profileStubId) throws Exception { // build node mockMvc.perform(post("/v1/studies/{studyUuid}/nodes/{nodeUuid}/build", studyUuid, nodeUuid) .header(USER_ID_HEADER, userId)) @@ -2588,9 +2594,9 @@ private void testBuildAndStopWithNodeUuid(UUID studyUuid, UUID nodeUuid, String wireMockUtils.verifyPostRequest(buildOkStubId, "/v1/networks/" + NETWORK_UUID_STRING + "/build", Map.of(QUERY_PARAM_RECEIVER, WireMock.matching(".*"))); wireMockUtils.verifyGetRequest(profileStubId, "/v1/users/" + userId + "/profile/max-builds", Map.of()); - assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(nodeUuid).getGlobalBuildStatus()); // node is built + assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(nodeUuid, rootNetworkUuid).getGlobalBuildStatus()); // node is built - networkModificationTreeService.updateNodeBuildStatus(nodeUuid, NodeBuildStatus.from(BuildStatus.BUILDING)); + networkModificationTreeService.updateNodeBuildStatus(nodeUuid, rootNetworkUuid, NodeBuildStatus.from(BuildStatus.BUILDING)); // stop build mockMvc.perform(put("/v1/studies/{studyUuid}/nodes/{nodeUuid}/build/stop", studyUuid, nodeUuid)) @@ -2605,13 +2611,13 @@ private void testBuildAndStopWithNodeUuid(UUID studyUuid, UUID nodeUuid, String assertEquals(studyUuid, buildStatusMessage.getHeaders().get(NotificationService.HEADER_STUDY_UUID)); assertEquals(nodeUuid, buildStatusMessage.getHeaders().get(NotificationService.HEADER_NODE)); assertEquals(NotificationService.UPDATE_TYPE_BUILD_CANCELLED, buildStatusMessage.getHeaders().get(NotificationService.HEADER_UPDATE_TYPE)); - assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(nodeUuid).getGlobalBuildStatus()); // node is not built + assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(nodeUuid, rootNetworkUuid).getGlobalBuildStatus()); // node is not built wireMockUtils.verifyPutRequest(buildStopStubId, "/v1/build/stop", true, Map.of(QUERY_PARAM_RECEIVER, WireMock.matching(".*")), null); } // builds on network 2 will fail - private void testBuildFailedWithNodeUuid(UUID studyUuid, UUID nodeUuid) throws Exception { + private void testBuildFailedWithNodeUuid(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid) throws Exception { // build node mockMvc.perform(post("/v1/studies/{studyUuid}/nodes/{nodeUuid}/build", studyUuid, nodeUuid) .header(USER_ID_HEADER, USER_ID)) @@ -2637,11 +2643,11 @@ private void testBuildFailedWithNodeUuid(UUID studyUuid, UUID nodeUuid) throws E wireMockUtils.verifyPostRequest(buildFailedStubId, "/v1/networks/" + NETWORK_UUID_2_STRING + "/build", Map.of(QUERY_PARAM_RECEIVER, WireMock.matching(".*"))); wireMockUtils.verifyGetRequest(userProfileQuotaStubId, "/v1/users/" + USER_ID + "/profile/max-builds", Map.of()); - assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(nodeUuid).getGlobalBuildStatus()); // node is not built + assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(nodeUuid, rootNetworkUuid).getGlobalBuildStatus()); // node is not built } // builds on network 3 will throw an error on networkmodificationservice call - private void testBuildErrorWithNodeUuid(UUID studyUuid, UUID nodeUuid) throws Exception { + private void testBuildErrorWithNodeUuid(UUID studyUuid, UUID nodeUuid, UUID rootNetworkUuid) throws Exception { // build node mockMvc.perform(post("/v1/studies/{studyUuid}/nodes/{nodeUuid}/build", studyUuid, nodeUuid) .header(USER_ID_HEADER, USER_ID)) @@ -2660,7 +2666,7 @@ private void testBuildErrorWithNodeUuid(UUID studyUuid, UUID nodeUuid) throws Ex wireMockUtils.verifyPostRequest(buildErrorStubId, "/v1/networks/" + NETWORK_UUID_3_STRING + "/build", Map.of(QUERY_PARAM_RECEIVER, WireMock.matching(".*"))); wireMockUtils.verifyGetRequest(userProfileQuotaStubId, "/v1/users/" + USER_ID + "/profile/max-builds", Map.of()); - assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(nodeUuid).getGlobalBuildStatus()); // node is not built + assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(nodeUuid, rootNetworkUuid).getGlobalBuildStatus()); // node is not built } private void checkEquipmentCreatingMessagesReceived(UUID studyNameUserIdUuid, UUID nodeUuid) { @@ -2801,9 +2807,9 @@ private void checkNodesInvalidationMessagesReceived(UUID studyNameUserIdUuid, Li } private StudyEntity insertDummyStudy(UUID networkUuid, UUID caseUuid, String caseFormat) { - StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, caseUuid, caseFormat, UUID.randomUUID(), null, null, null, null); + StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, "netId", caseUuid, caseFormat, "", null, UUID.randomUUID(), null, null, null, null); var study = studyRepository.save(studyEntity); - networkModificationTreeService.createRoot(studyEntity, null); + networkModificationTreeService.createRoot(studyEntity); return study; } diff --git a/src/test/java/org/gridsuite/study/server/NetworkModificationTreeTest.java b/src/test/java/org/gridsuite/study/server/NetworkModificationTreeTest.java index 623dea831..06ee3e0a0 100644 --- a/src/test/java/org/gridsuite/study/server/NetworkModificationTreeTest.java +++ b/src/test/java/org/gridsuite/study/server/NetworkModificationTreeTest.java @@ -31,13 +31,19 @@ import org.gridsuite.study.server.dto.NodeModificationInfos; import org.gridsuite.study.server.dto.modification.NetworkModificationResult; import org.gridsuite.study.server.networkmodificationtree.dto.*; +import org.gridsuite.study.server.networkmodificationtree.entities.NetworkModificationNodeInfoEntity; import org.gridsuite.study.server.networkmodificationtree.entities.NodeType; +import org.gridsuite.study.server.networkmodificationtree.entities.RootNodeInfoEntity; +import org.gridsuite.study.server.networkmodificationtree.entities.RootNetworkNodeInfoEntity; import org.gridsuite.study.server.notification.NotificationService; import org.gridsuite.study.server.repository.StudyEntity; import org.gridsuite.study.server.repository.StudyRepository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkEntity; import org.gridsuite.study.server.repository.networkmodificationtree.NetworkModificationNodeInfoRepository; import org.gridsuite.study.server.repository.networkmodificationtree.NodeRepository; import org.gridsuite.study.server.repository.networkmodificationtree.RootNodeInfoRepository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkNodeInfoRepository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkRepository; import org.gridsuite.study.server.service.*; import org.gridsuite.study.server.service.shortcircuit.ShortCircuitService; import org.gridsuite.study.server.utils.TestUtils; @@ -181,6 +187,11 @@ class NetworkModificationTreeTest { private static final String STUDY_UPDATE_DESTINATION = "study.update"; private static final String ELEMENT_UPDATE_DESTINATION = "element.update"; + @Autowired + private RootNetworkNodeInfoRepository rootNetworkNodeInfoRepository; + @Autowired + private RootNetworkRepository rootNetworkRepository; + @BeforeEach void setUp(final MockWebServer server) { Configuration.defaultConfiguration(); @@ -282,12 +293,16 @@ void tearDown() { } private static StudyEntity createDummyStudy(UUID networkUuid) { - return StudyEntity.builder().id(UUID.randomUUID()).caseFormat("").caseUuid(UUID.randomUUID()) - .caseName("caseName1") - .networkId("netId") - .networkUuid(networkUuid) + StudyEntity studyEntity = StudyEntity.builder().id(UUID.randomUUID()) .shortCircuitParametersUuid(UUID.randomUUID()) .build(); + studyEntity.addRootNetwork(RootNetworkEntity.builder() + .caseFormat("").caseUuid(UUID.randomUUID()) + .reportUuid(UUID.randomUUID()) + .caseName("caseName1") + .networkId("netId") + .networkUuid(networkUuid).build()); + return studyEntity; } @Test @@ -515,25 +530,27 @@ private UUID createNodeTree() throws Exception { @Test void testNodeModificationInfos() throws Exception { UUID rootStudyId = createNodeTree(); + UUID rootNetworkUuid = rootNetworkRepository.findAllByStudyId(rootStudyId).stream().findFirst().orElseThrow(() -> new StudyException(StudyException.Type.ROOTNETWORK_NOT_FOUND)).getId(); RootNode root = getRootNode(rootStudyId); UUID rootId = root.getId(); - NodeModificationInfos rootInfos = networkModificationTreeService.getNodeModificationInfos(rootId); + RootNodeInfoEntity rootInfos = rootNodeInfoRepository.findById(rootId).orElseThrow(() -> new StudyException(StudyException.Type.NODE_NOT_FOUND)); assertEquals(rootId, rootInfos.getId()); List children = root.getChildren(); assertEquals(2, children.size()); NetworkModificationNode n1 = (NetworkModificationNode) children.get(0); - NodeModificationInfos n1Infos = networkModificationTreeService.getNodeModificationInfos(n1.getId()); + NetworkModificationNodeInfoEntity n1Infos = networkModificationTreeService.getNetworkModificationNodeInfoEntity(n1.getId()); + RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = rootNetworkNodeInfoRepository.findByNodeInfoIdAndRootNetworkId(n1.getId(), rootNetworkUuid).orElseThrow(() -> new StudyException(StudyException.Type.ROOTNETWORK_NOT_FOUND)); assertEquals("n1", n1.getName()); assertEquals("zzz", n1.getDescription()); assertFalse(n1.getNodeBuildStatus().isBuilt()); assertEquals(n1.getId(), n1Infos.getId()); assertEquals(MODIFICATION_GROUP_UUID, n1Infos.getModificationGroupUuid()); - assertEquals(VARIANT_ID, n1Infos.getVariantId()); + assertEquals(VARIANT_ID, rootNetworkNodeInfoEntity.getVariantId()); UUID badUuid = UUID.randomUUID(); - assertThrows(StudyException.class, () -> networkModificationTreeService.getNodeModificationInfos(badUuid), "ELEMENT_NOT_FOUND"); + assertThrows(StudyException.class, () -> networkModificationTreeService.getNetworkModificationNodeInfoEntity(badUuid), "ELEMENT_NOT_FOUND"); } @Test @@ -782,14 +799,15 @@ void testInsertAfter() throws Exception { var grandChildren = getRootNode(root.getStudyId()).getChildren().get(0).getChildren().stream().map(AbstractNode::getId).collect(Collectors.toSet()); assertEquals(originalChildren, grandChildren); - assertEquals(VARIANT_ID, networkModificationTreeService.getVariantId(node1.getId())); + UUID rootNetworkUuid = rootNetworkRepository.findAllByStudyId(root.getStudyId()).stream().findFirst().orElseThrow(() -> new StudyException(StudyException.Type.ROOTNETWORK_NOT_FOUND)).getId(); + assertEquals(VARIANT_ID, networkModificationTreeService.getVariantId(node1.getId(), rootNetworkUuid)); UUID nodeUuid = node2.getId(); assertNotNull(networkModificationTreeService.getModificationGroupUuid(nodeUuid)); - assertNotNull(networkModificationTreeService.getReportUuid(nodeUuid)); - assertFalse(networkModificationTreeService.getVariantId(nodeUuid).isEmpty()); + assertNotNull(networkModificationTreeService.getReportUuid(nodeUuid, rootNetworkUuid)); + assertFalse(networkModificationTreeService.getVariantId(nodeUuid, rootNetworkUuid).isEmpty()); - assertEquals(4, networkModificationTreeService.getAllNodesModificationInfos(root.getStudyId()).stream().map(NodeModificationInfos::getReportUuid).collect(Collectors.toList()).size()); + assertEquals(4, networkModificationTreeService.getAllNodesModificationInfos(root.getStudyId()).stream().map(NodeModificationInfos::getReportUuid).filter(Objects::nonNull).collect(Collectors.toList()).size()); } @Test @@ -937,9 +955,10 @@ void testGetLastParentNodeBuilt() throws Exception { createNode(root.getStudyId(), node3, node10, userId); createNode(root.getStudyId(), node10, node9, userId); - assertEquals(node7.getId(), networkModificationTreeService.doGetLastParentNodeBuiltUuid(node7.getId())); - assertEquals(node7.getId(), networkModificationTreeService.doGetLastParentNodeBuiltUuid(node9.getId())); - assertEquals(node7.getId(), networkModificationTreeService.doGetLastParentNodeBuiltUuid(node3.getId())); + UUID rootNetworkUuid = rootNetworkRepository.findAllByStudyId(root.getStudyId()).stream().findFirst().orElseThrow(() -> new StudyException(StudyException.Type.ROOTNETWORK_NOT_FOUND)).getId(); + assertEquals(node7.getId(), networkModificationTreeService.doGetLastParentNodeBuiltUuid(node7.getId(), rootNetworkUuid)); + assertEquals(node7.getId(), networkModificationTreeService.doGetLastParentNodeBuiltUuid(node9.getId(), rootNetworkUuid)); + assertEquals(node7.getId(), networkModificationTreeService.doGetLastParentNodeBuiltUuid(node3.getId(), rootNetworkUuid)); } private void createNode(UUID studyUuid, AbstractNode parentNode, NetworkModificationNode newNode, String userId) throws Exception { @@ -999,7 +1018,7 @@ private void insertNode(UUID studyUuid, AbstractNode parentNode, NetworkModifica private StudyEntity insertDummyStudy() { StudyEntity studyEntity = createDummyStudy(NETWORK_UUID); var study = studyRepository.save(studyEntity); - networkModificationTreeService.createRoot(studyEntity, null); + networkModificationTreeService.createRoot(studyEntity); return study; } @@ -1061,7 +1080,7 @@ void testNodeName() throws Exception { UUID studyUuid = root.getStudyId(); createNode(studyUuid, root, node, userId); createNodeFail(studyUuid, root, root); - createNodeFail(studyUuid, root, node); + createNodeForbidden(studyUuid, root, node); node.setName("node 2"); createNode(studyUuid, root, node, userId); @@ -1081,7 +1100,15 @@ private void createNodeFail(UUID studyUuid, AbstractNode parentNode, AbstractNod .contentType(MediaType.APPLICATION_JSON) .content(objectWriter.writeValueAsString(newNode)) .header(USER_ID_HEADER, "userId")) - .andExpect(status().isForbidden()); + .andExpect(status().isBadRequest()); + } + + private void createNodeForbidden(UUID studyUuid, AbstractNode parentNode, AbstractNode newNode) throws Exception { + mockMvc.perform(post("/v1/studies/{studyUuid}/tree/nodes/{id}", studyUuid, parentNode.getId()) + .contentType(MediaType.APPLICATION_JSON) + .content(objectWriter.writeValueAsString(newNode)) + .header(USER_ID_HEADER, "userId")) + .andExpect(status().isForbidden()); } private String getNodeName(UUID studyUuid) throws Exception { @@ -1198,33 +1225,34 @@ void testUpdateBuildStatus() throws Exception { Pair result = createTreeForBuildStatus(); UUID leafNodeId = result.getSecond().getId(); UUID studyUuid = result.getFirst(); + UUID rootNetworkUuid = rootNetworkRepository.findAllByStudyId(studyUuid).stream().findFirst().orElseThrow(() -> new StudyException(StudyException.Type.ROOTNETWORK_NOT_FOUND)).getId(); - networkModificationTreeService.updateNodeBuildStatus(leafNodeId, NodeBuildStatus.from(BuildStatus.BUILT_WITH_WARNING)); - assertEquals(BuildStatus.BUILT_WITH_WARNING, networkModificationTreeService.getNodeBuildStatus(leafNodeId).getGlobalBuildStatus()); + networkModificationTreeService.updateNodeBuildStatus(leafNodeId, rootNetworkUuid, NodeBuildStatus.from(BuildStatus.BUILT_WITH_WARNING)); + assertEquals(BuildStatus.BUILT_WITH_WARNING, networkModificationTreeService.getNodeBuildStatus(leafNodeId, rootNetworkUuid).getGlobalBuildStatus()); checkUpdateNodesMessageReceived(studyUuid, List.of(leafNodeId)); - networkModificationTreeService.updateNodeBuildStatus(leafNodeId, NodeBuildStatus.from(BuildStatus.BUILT_WITH_ERROR)); - assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(leafNodeId).getLocalBuildStatus()); - assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(leafNodeId).getGlobalBuildStatus()); + networkModificationTreeService.updateNodeBuildStatus(leafNodeId, rootNetworkUuid, NodeBuildStatus.from(BuildStatus.BUILT_WITH_ERROR)); + assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(leafNodeId, rootNetworkUuid).getLocalBuildStatus()); + assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(leafNodeId, rootNetworkUuid).getGlobalBuildStatus()); checkUpdateNodesMessageReceived(studyUuid, List.of(leafNodeId)); // keep the previous status (BUILT_WITH_ERROR) because it has higher severity - networkModificationTreeService.updateNodeBuildStatus(leafNodeId, NodeBuildStatus.from(BuildStatus.BUILT_WITH_WARNING)); - assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(leafNodeId).getGlobalBuildStatus()); + networkModificationTreeService.updateNodeBuildStatus(leafNodeId, rootNetworkUuid, NodeBuildStatus.from(BuildStatus.BUILT_WITH_WARNING)); + assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(leafNodeId, rootNetworkUuid).getGlobalBuildStatus()); // no update because the status didn't change - networkModificationTreeService.updateNodeBuildStatus(leafNodeId, NodeBuildStatus.from(BuildStatus.BUILDING)); - assertEquals(BuildStatus.BUILDING, networkModificationTreeService.getNodeBuildStatus(leafNodeId).getGlobalBuildStatus()); + networkModificationTreeService.updateNodeBuildStatus(leafNodeId, rootNetworkUuid, NodeBuildStatus.from(BuildStatus.BUILDING)); + assertEquals(BuildStatus.BUILDING, networkModificationTreeService.getNodeBuildStatus(leafNodeId, rootNetworkUuid).getGlobalBuildStatus()); checkUpdateNodesMessageReceived(studyUuid, List.of(leafNodeId)); - networkModificationTreeService.updateNodeBuildStatus(leafNodeId, NodeBuildStatus.from(BuildStatus.NOT_BUILT)); - assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(leafNodeId).getGlobalBuildStatus()); + networkModificationTreeService.updateNodeBuildStatus(leafNodeId, rootNetworkUuid, NodeBuildStatus.from(BuildStatus.NOT_BUILT)); + assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(leafNodeId, rootNetworkUuid).getGlobalBuildStatus()); checkUpdateNodesMessageReceived(studyUuid, List.of(leafNodeId)); // take the closest built parent severity - networkModificationTreeService.updateNodeBuildStatus(leafNodeId, NodeBuildStatus.from(BuildStatus.BUILT)); - assertEquals(BuildStatus.BUILT_WITH_WARNING, networkModificationTreeService.getNodeBuildStatus(leafNodeId).getGlobalBuildStatus()); - assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(leafNodeId).getLocalBuildStatus()); + networkModificationTreeService.updateNodeBuildStatus(leafNodeId, rootNetworkUuid, NodeBuildStatus.from(BuildStatus.BUILT)); + assertEquals(BuildStatus.BUILT_WITH_WARNING, networkModificationTreeService.getNodeBuildStatus(leafNodeId, rootNetworkUuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(leafNodeId, rootNetworkUuid).getLocalBuildStatus()); checkUpdateNodesMessageReceived(studyUuid, List.of(leafNodeId)); } @@ -1233,28 +1261,29 @@ void testUpdateApplicationStatus() throws Exception { Pair result = createTreeForBuildStatus(); UUID leafNodeId = result.getSecond().getId(); UUID studyUuid = result.getFirst(); + UUID rootNetworkUuid = rootNetworkRepository.findAllByStudyId(studyUuid).stream().findFirst().orElseThrow(() -> new StudyException(StudyException.Type.ROOTNETWORK_NOT_FOUND)).getId(); // take the closest built parent severity - networkModificationTreeService.updateNodeBuildStatus(leafNodeId, NodeBuildStatus.from(NetworkModificationResult.ApplicationStatus.ALL_OK, NetworkModificationResult.ApplicationStatus.WITH_WARNINGS)); - assertEquals(BuildStatus.BUILT_WITH_WARNING, networkModificationTreeService.getNodeBuildStatus(leafNodeId).getGlobalBuildStatus()); - assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(leafNodeId).getLocalBuildStatus()); + networkModificationTreeService.updateNodeBuildStatus(leafNodeId, rootNetworkUuid, NodeBuildStatus.from(NetworkModificationResult.ApplicationStatus.ALL_OK, NetworkModificationResult.ApplicationStatus.WITH_WARNINGS)); + assertEquals(BuildStatus.BUILT_WITH_WARNING, networkModificationTreeService.getNodeBuildStatus(leafNodeId, rootNetworkUuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(leafNodeId, rootNetworkUuid).getLocalBuildStatus()); checkUpdateNodesMessageReceived(studyUuid, List.of(leafNodeId)); - networkModificationTreeService.updateNodeBuildStatus(leafNodeId, NodeBuildStatus.from(NetworkModificationResult.ApplicationStatus.WITH_WARNINGS, NetworkModificationResult.ApplicationStatus.WITH_WARNINGS)); - assertEquals(BuildStatus.BUILT_WITH_WARNING, networkModificationTreeService.getNodeBuildStatus(leafNodeId).getGlobalBuildStatus()); - assertEquals(BuildStatus.BUILT_WITH_WARNING, networkModificationTreeService.getNodeBuildStatus(leafNodeId).getLocalBuildStatus()); + networkModificationTreeService.updateNodeBuildStatus(leafNodeId, rootNetworkUuid, NodeBuildStatus.from(NetworkModificationResult.ApplicationStatus.WITH_WARNINGS, NetworkModificationResult.ApplicationStatus.WITH_WARNINGS)); + assertEquals(BuildStatus.BUILT_WITH_WARNING, networkModificationTreeService.getNodeBuildStatus(leafNodeId, rootNetworkUuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.BUILT_WITH_WARNING, networkModificationTreeService.getNodeBuildStatus(leafNodeId, rootNetworkUuid).getLocalBuildStatus()); // local build status has been updated checkUpdateNodesMessageReceived(studyUuid, List.of(leafNodeId)); - networkModificationTreeService.updateNodeBuildStatus(leafNodeId, NodeBuildStatus.from(NetworkModificationResult.ApplicationStatus.WITH_ERRORS, NetworkModificationResult.ApplicationStatus.WITH_ERRORS)); - assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(leafNodeId).getGlobalBuildStatus()); - assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(leafNodeId).getLocalBuildStatus()); + networkModificationTreeService.updateNodeBuildStatus(leafNodeId, rootNetworkUuid, NodeBuildStatus.from(NetworkModificationResult.ApplicationStatus.WITH_ERRORS, NetworkModificationResult.ApplicationStatus.WITH_ERRORS)); + assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(leafNodeId, rootNetworkUuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(leafNodeId, rootNetworkUuid).getLocalBuildStatus()); checkUpdateNodesMessageReceived(studyUuid, List.of(leafNodeId)); // keep the previous status (BUILT_WITH_ERROR) because it has higher severity - networkModificationTreeService.updateNodeBuildStatus(leafNodeId, NodeBuildStatus.from(NetworkModificationResult.ApplicationStatus.ALL_OK, NetworkModificationResult.ApplicationStatus.WITH_ERRORS)); - assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(leafNodeId).getGlobalBuildStatus()); - assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(leafNodeId).getLocalBuildStatus()); + networkModificationTreeService.updateNodeBuildStatus(leafNodeId, rootNetworkUuid, NodeBuildStatus.from(NetworkModificationResult.ApplicationStatus.ALL_OK, NetworkModificationResult.ApplicationStatus.WITH_ERRORS)); + assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(leafNodeId, rootNetworkUuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.BUILT_WITH_ERROR, networkModificationTreeService.getNodeBuildStatus(leafNodeId, rootNetworkUuid).getLocalBuildStatus()); } /** diff --git a/src/test/java/org/gridsuite/study/server/NetworkModificationUnitTest.java b/src/test/java/org/gridsuite/study/server/NetworkModificationUnitTest.java index 3a84b65c4..6b8ab766e 100644 --- a/src/test/java/org/gridsuite/study/server/NetworkModificationUnitTest.java +++ b/src/test/java/org/gridsuite/study/server/NetworkModificationUnitTest.java @@ -6,25 +6,21 @@ */ package org.gridsuite.study.server; -import com.powsybl.network.store.client.NetworkStoreService; +import org.gridsuite.study.server.dto.StudyIndexationStatus; import org.gridsuite.study.server.networkmodificationtree.dto.BuildStatus; import org.gridsuite.study.server.networkmodificationtree.dto.NodeBuildStatus; -import org.gridsuite.study.server.networkmodificationtree.entities.NetworkModificationNodeInfoEntity; -import org.gridsuite.study.server.networkmodificationtree.entities.NodeEntity; -import org.gridsuite.study.server.networkmodificationtree.entities.NodeType; -import org.gridsuite.study.server.networkmodificationtree.entities.RootNodeInfoEntity; +import org.gridsuite.study.server.networkmodificationtree.entities.*; import org.gridsuite.study.server.notification.NotificationService; import org.gridsuite.study.server.repository.StudyEntity; import org.gridsuite.study.server.repository.StudyRepository; import org.gridsuite.study.server.repository.networkmodificationtree.NetworkModificationNodeInfoRepository; import org.gridsuite.study.server.repository.networkmodificationtree.NodeRepository; import org.gridsuite.study.server.repository.networkmodificationtree.RootNodeInfoRepository; -import org.gridsuite.study.server.repository.nonevacuatedenergy.NonEvacuatedEnergyParametersEntity; -import org.gridsuite.study.server.service.NetworkModificationTreeService; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkEntity; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkNodeInfoRepository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkRepository; +import org.gridsuite.study.server.repository.voltageinit.StudyVoltageInitParametersEntity; import org.gridsuite.study.server.service.NetworkService; -import org.gridsuite.study.server.service.NonEvacuatedEnergyService; -import org.gridsuite.study.server.service.ReportService; -import org.gridsuite.study.server.utils.TestUtils; import org.gridsuite.study.server.utils.elasticsearch.DisableElasticsearch; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -40,8 +36,8 @@ import org.springframework.messaging.MessageHeaders; import org.springframework.web.client.RestTemplate; -import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.UUID; import java.util.stream.Collectors; @@ -63,16 +59,10 @@ class NetworkModificationUnitTest { @Autowired private RootNodeInfoRepository rootNodeInfoRepository; @Autowired - private NetworkModificationTreeService networkModificationTreeService; - @Autowired private StudyRepository studyRepository; @Autowired private StudyController studyController; @MockBean - private ReportService reportService; - @MockBean - private NetworkStoreService networkStoreService; - @MockBean private NetworkService networkService; @MockBean private RestTemplate restTemplate; @@ -85,6 +75,12 @@ class NetworkModificationUnitTest { private static final long TIMEOUT = 1000; private static final String VARIANT_1 = "variant_1"; + private static final String VARIANT_2 = "variant_2"; + private static final String VARIANT_3 = "variant_3"; + + private static final UUID REPORT_UUID_1 = UUID.randomUUID(); + private static final UUID REPORT_UUID_2 = UUID.randomUUID(); + private static final UUID REPORT_UUID_3 = UUID.randomUUID(); private UUID studyUuid; private UUID node1Uuid; @@ -95,17 +91,31 @@ class NetworkModificationUnitTest { @Autowired private OutputDestination output; private static final String STUDY_UPDATE_DESTINATION = "study.update"; + @Autowired + private RootNetworkNodeInfoRepository rootNetworkNodeInfoRepository; + @Autowired + private RootNetworkRepository rootNetworkRepository; @BeforeEach void setup() { - StudyEntity study = insertStudy(NETWORK_UUID, CASE_LOADFLOW_UUID); + StudyEntity study = insertStudy(); + + RootNetworkEntity firstRootNetworkEntity = RootNetworkEntity.builder() + .networkUuid(NETWORK_UUID) + .networkId("netId") + .caseUuid(CASE_LOADFLOW_UUID) + .caseFormat("caseFormat") + .caseName("caseName") + .build(); + + study.addRootNetwork(firstRootNetworkEntity); + studyRepository.save(study); studyUuid = study.getId(); - NodeEntity rootNode = insertRootNode(study, UUID.randomUUID()); - - NodeEntity node1 = insertNode(study, node1Uuid, rootNode, BuildStatus.BUILT); - NodeEntity node2 = insertNode(study, node2Uuid, node1, BuildStatus.BUILT); - NodeEntity node3 = insertNode(study, node3Uuid, node1, BuildStatus.NOT_BUILT); + NodeEntity node1 = insertNode(study, node1Uuid, VARIANT_1, REPORT_UUID_1, rootNode, firstRootNetworkEntity, BuildStatus.BUILT); + NodeEntity node2 = insertNode(study, node2Uuid, VARIANT_2, REPORT_UUID_2, node1, firstRootNetworkEntity, BuildStatus.BUILT); + NodeEntity node3 = insertNode(study, node3Uuid, VARIANT_3, REPORT_UUID_3, node1, firstRootNetworkEntity, BuildStatus.NOT_BUILT); + rootNetworkRepository.save(firstRootNetworkEntity); node1Uuid = node1.getIdNode(); node2Uuid = node2.getIdNode(); @@ -120,14 +130,12 @@ void unbuildNode() { * | | * node2(B) node3 */ - List nodesInfos = networkModificationNodeInfoRepository.findAll(); - NetworkModificationNodeInfoEntity node1Infos = nodesInfos.stream().filter(n -> n.getIdNode().equals(node1Uuid)).findAny().orElseThrow(() -> new UnsupportedOperationException(SHOULD_NOT_RETURN_NULL_MESSAGE)); - NetworkModificationNodeInfoEntity node2Infos = nodesInfos.stream().filter(n -> n.getIdNode().equals(node2Uuid)).findAny().orElseThrow(() -> new UnsupportedOperationException(SHOULD_NOT_RETURN_NULL_MESSAGE)); - NetworkModificationNodeInfoEntity node3Infos = nodesInfos.stream().filter(n -> n.getIdNode().equals(node3Uuid)).findAny().orElseThrow(() -> new UnsupportedOperationException(SHOULD_NOT_RETURN_NULL_MESSAGE)); - - assertEquals(BuildStatus.BUILT, node1Infos.getNodeBuildStatus().getLocalBuildStatus()); - assertEquals(BuildStatus.BUILT, node2Infos.getNodeBuildStatus().getLocalBuildStatus()); - assertEquals(BuildStatus.NOT_BUILT, node3Infos.getNodeBuildStatus().getLocalBuildStatus()); + RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity1 = rootNetworkNodeInfoRepository.findAllByNodeInfoId(node1Uuid).stream().findFirst().orElseThrow(() -> new StudyException(StudyException.Type.ROOTNETWORK_NOT_FOUND)); + RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity2 = rootNetworkNodeInfoRepository.findAllByNodeInfoId(node2Uuid).stream().findFirst().orElseThrow(() -> new StudyException(StudyException.Type.ROOTNETWORK_NOT_FOUND)); + RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity3 = rootNetworkNodeInfoRepository.findAllByNodeInfoId(node3Uuid).stream().findFirst().orElseThrow(() -> new StudyException(StudyException.Type.ROOTNETWORK_NOT_FOUND)); + assertEquals(BuildStatus.BUILT, rootNetworkNodeInfoEntity1.getNodeBuildStatus().getLocalBuildStatus()); + assertEquals(BuildStatus.BUILT, rootNetworkNodeInfoEntity2.getNodeBuildStatus().getLocalBuildStatus()); + assertEquals(BuildStatus.NOT_BUILT, rootNetworkNodeInfoEntity3.getNodeBuildStatus().getLocalBuildStatus()); studyController.unbuildNode(studyUuid, node1Uuid); @@ -137,19 +145,17 @@ void unbuildNode() { * | | * node2(B) node3 */ - nodesInfos = networkModificationNodeInfoRepository.findAll(); - node1Infos = nodesInfos.stream().filter(n -> n.getIdNode().equals(node1Uuid)).findAny().orElseThrow(() -> new UnsupportedOperationException(SHOULD_NOT_RETURN_NULL_MESSAGE)); - node2Infos = nodesInfos.stream().filter(n -> n.getIdNode().equals(node2Uuid)).findAny().orElseThrow(() -> new UnsupportedOperationException(SHOULD_NOT_RETURN_NULL_MESSAGE)); - node3Infos = nodesInfos.stream().filter(n -> n.getIdNode().equals(node3Uuid)).findAny().orElseThrow(() -> new UnsupportedOperationException(SHOULD_NOT_RETURN_NULL_MESSAGE)); - - assertEquals(BuildStatus.NOT_BUILT, node1Infos.getNodeBuildStatus().getLocalBuildStatus()); - assertEquals(BuildStatus.BUILT, node2Infos.getNodeBuildStatus().getLocalBuildStatus()); - assertEquals(BuildStatus.NOT_BUILT, node3Infos.getNodeBuildStatus().getLocalBuildStatus()); + rootNetworkNodeInfoEntity1 = rootNetworkNodeInfoRepository.findAllByNodeInfoId(node1Uuid).stream().findFirst().orElseThrow(() -> new StudyException(StudyException.Type.ROOTNETWORK_NOT_FOUND)); + rootNetworkNodeInfoEntity2 = rootNetworkNodeInfoRepository.findAllByNodeInfoId(node2Uuid).stream().findFirst().orElseThrow(() -> new StudyException(StudyException.Type.ROOTNETWORK_NOT_FOUND)); + rootNetworkNodeInfoEntity3 = rootNetworkNodeInfoRepository.findAllByNodeInfoId(node3Uuid).stream().findFirst().orElseThrow(() -> new StudyException(StudyException.Type.ROOTNETWORK_NOT_FOUND)); + assertEquals(BuildStatus.NOT_BUILT, rootNetworkNodeInfoEntity1.getNodeBuildStatus().getLocalBuildStatus()); + assertEquals(BuildStatus.BUILT, rootNetworkNodeInfoEntity2.getNodeBuildStatus().getLocalBuildStatus()); + assertEquals(BuildStatus.NOT_BUILT, rootNetworkNodeInfoEntity3.getNodeBuildStatus().getLocalBuildStatus()); checkUpdateBuildStateMessageReceived(studyUuid, List.of(node1Uuid)); checkUpdateModelsStatusMessagesReceived(studyUuid, node1Uuid); - Mockito.verify(networkService).deleteVariants(null, List.of(VARIANT_1)); + Mockito.verify(networkService).deleteVariants(NETWORK_UUID, List.of(VARIANT_1)); } @Test @@ -224,18 +230,24 @@ private void checkUpdateModelsStatusMessagesReceived(UUID studyUuid, UUID nodeUu checkUpdateModelStatusMessagesReceived(studyUuid, nodeUuid, NotificationService.UPDATE_TYPE_STATE_ESTIMATION_STATUS); } - private StudyEntity insertStudy(UUID networkUuid, UUID caseUuid) { - NonEvacuatedEnergyParametersEntity defaultNonEvacuatedEnergyParametersEntity = NonEvacuatedEnergyService.toEntity(NonEvacuatedEnergyService.getDefaultNonEvacuatedEnergyParametersInfos()); - StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, caseUuid, "", - UUID.randomUUID(), null, null, null, defaultNonEvacuatedEnergyParametersEntity); - return studyRepository.save(studyEntity); + private StudyEntity insertStudy() { + return StudyEntity.builder() + .id(UUID.randomUUID()) + .indexationStatus(StudyIndexationStatus.INDEXED) + .voltageInitParameters(new StudyVoltageInitParametersEntity()) + .build(); } - private NodeEntity insertNode(StudyEntity study, UUID nodeId, NodeEntity parentNode, BuildStatus buildStatus) { + private NodeEntity insertNode(StudyEntity study, UUID nodeId, String variantId, UUID reportUuid, NodeEntity parentNode, RootNetworkEntity rootNetworkEntity, BuildStatus buildStatus) { NodeEntity node = nodeRepository.save(new NodeEntity(nodeId, parentNode, NodeType.NETWORK_MODIFICATION, study, false, null)); - NetworkModificationNodeInfoEntity nodeInfos = new NetworkModificationNodeInfoEntity(UUID.randomUUID(), VARIANT_1, null, null, null, null, null, null, null, null, null, NodeBuildStatus.from(buildStatus).toEntity(), new HashMap<>(), new HashMap<>()); + NetworkModificationNodeInfoEntity nodeInfos = NetworkModificationNodeInfoEntity.builder().modificationGroupUuid(UUID.randomUUID()).build(); + RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = RootNetworkNodeInfoEntity.builder().variantId(variantId).modificationReports(Map.of(node.getIdNode(), reportUuid)).nodeBuildStatus(NodeBuildStatus.from(buildStatus).toEntity()).build(); + nodeInfos.addRootNetworkNodeInfo(rootNetworkNodeInfoEntity); + rootNetworkEntity.addRootNetworkNodeInfo(rootNetworkNodeInfoEntity); + nodeInfos.setIdNode(node.getIdNode()); networkModificationNodeInfoRepository.save(nodeInfos); + rootNetworkNodeInfoRepository.save(rootNetworkNodeInfoEntity); return node; } diff --git a/src/test/java/org/gridsuite/study/server/NonEvacuatedEnergyTest.java b/src/test/java/org/gridsuite/study/server/NonEvacuatedEnergyTest.java index 9d84dc779..5e3881c8a 100644 --- a/src/test/java/org/gridsuite/study/server/NonEvacuatedEnergyTest.java +++ b/src/test/java/org/gridsuite/study/server/NonEvacuatedEnergyTest.java @@ -30,7 +30,7 @@ import org.gridsuite.study.server.notification.NotificationService; import org.gridsuite.study.server.repository.StudyEntity; import org.gridsuite.study.server.repository.StudyRepository; -import org.gridsuite.study.server.repository.networkmodificationtree.NetworkModificationNodeInfoRepository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkNodeInfoRepository; import org.gridsuite.study.server.repository.nonevacuatedenergy.NonEvacuatedEnergyParametersEntity; import org.gridsuite.study.server.service.*; import org.gridsuite.study.server.utils.SendInput; @@ -141,7 +141,7 @@ class NonEvacuatedEnergyTest { private StudyRepository studyRepository; @Autowired - private NetworkModificationNodeInfoRepository networkModificationNodeInfoRepository; + private RootNetworkNodeInfoRepository rootNetworkNodeInfoRepository; @Autowired private ReportService reportService; @@ -185,13 +185,13 @@ public MockResponse dispatch(RecordedRequest request) { input.send(MessageBuilder.withPayload("") .setHeader("resultUuid", resultUuid) .setHeader(HEADER_USER_ID, "userId") - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .build(), NON_EVACUATED_ENERGY_RESULT_DESTINATION); return new MockResponse(200, Headers.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE), "\"" + resultUuid + "\""); } else if (path.matches("/v1/networks/" + NETWORK_UUID_2_STRING + "/non-evacuated-energy.*")) { input.send(MessageBuilder.withPayload("") .setHeader(HEADER_USER_ID, "userId") - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .build(), NON_EVACUATED_ENERGY_FAILED_DESTINATION); return new MockResponse(200, Headers.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE), "\"" + NON_EVACUATED_ENERGY_ERROR_NODE_RESULT_UUID + "\""); } else if (path.matches("/v1/networks/" + NETWORK_UUID_3_STRING + "/non-evacuated-energy.*")) { @@ -203,7 +203,7 @@ public MockResponse dispatch(RecordedRequest request) { String resultUuid = path.matches(".*variantId=" + VARIANT_ID_3 + ".*") ? NON_EVACUATED_ENERGY_OTHER_NODE_RESULT_UUID : NON_EVACUATED_ENERGY_RESULT_UUID; input.send(MessageBuilder.withPayload("") .setHeader("resultUuid", resultUuid) - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .build(), NON_EVACUATED_ENERGY_STOPPED_DESTINATION); return new MockResponse(200); } else if (path.matches("/v1/non-evacuated-energy/results/" + NON_EVACUATED_ENERGY_OTHER_NODE_RESULT_UUID)) { @@ -347,7 +347,7 @@ void testNonEvacuatedEnergy(final MockWebServer server) throws Exception { assertTrue(TestUtils.getRequestsDone(1, server).stream().anyMatch(r -> r.matches("/v1/supervision/non-evacuated-energy/results-count"))); //Delete sensitivity analysis results - assertEquals(1, networkModificationNodeInfoRepository.findAllByNonEvacuatedEnergyResultUuidNotNull().size()); + assertEquals(1, rootNetworkNodeInfoRepository.findAllByNonEvacuatedEnergyResultUuidNotNull().size()); mockMvc.perform(delete("/v1/supervision/computation/results") .queryParam("type", ComputationType.NON_EVACUATED_ENERGY_ANALYSIS.toString()) .queryParam("dryRun", "false")) @@ -356,7 +356,7 @@ void testNonEvacuatedEnergy(final MockWebServer server) throws Exception { var requests = TestUtils.getRequestsDone(2, server); assertTrue(requests.contains("/v1/non-evacuated-energy/results")); assertTrue(requests.stream().anyMatch(r -> r.matches("/v1/reports"))); - assertEquals(0, networkModificationNodeInfoRepository.findAllByNonEvacuatedEnergyResultUuidNotNull().size()); + assertEquals(0, rootNetworkNodeInfoRepository.findAllByNonEvacuatedEnergyResultUuidNotNull().size()); String baseUrlWireMock = wireMock.baseUrl(); nonEvacuatedEnergyService.setSensitivityAnalysisServerBaseUri(baseUrlWireMock); @@ -373,6 +373,7 @@ void testGetSensitivityNonEvacuatedEnergyResultWithWrongId() throws Exception { StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID); UUID notFoundSensitivityUuid = UUID.randomUUID(); UUID studyUuid = studyEntity.getId(); + UUID rootNetworkUuid = studyEntity.getFirstRootNetwork().getId(); mockMvc.perform(get("/v1/studies/{studyUuid}/nodes/{nodeUuid}/non-evacuated-energy/result", studyUuid, UUID.randomUUID()) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isNoContent()).andReturn(); @@ -383,9 +384,9 @@ void testGetSensitivityNonEvacuatedEnergyResultWithWrongId() throws Exception { UUID rootNodeUuid = getRootNodeUuid(studyUuid); NetworkModificationNode modificationNode1 = createNetworkModificationNode(studyUuid, rootNodeUuid, UUID.randomUUID(), VARIANT_ID, "node 1"); UUID modificationNodeUuid = modificationNode1.getId(); - networkModificationTreeService.updateComputationResultUuid(modificationNodeUuid, notFoundSensitivityUuid, ComputationType.NON_EVACUATED_ENERGY_ANALYSIS); - assertTrue(networkModificationTreeService.getComputationResultUuid(modificationNodeUuid, ComputationType.NON_EVACUATED_ENERGY_ANALYSIS).isPresent()); - assertEquals(notFoundSensitivityUuid, networkModificationTreeService.getComputationResultUuid(modificationNodeUuid, ComputationType.NON_EVACUATED_ENERGY_ANALYSIS).get()); + networkModificationTreeService.updateComputationResultUuid(modificationNodeUuid, rootNetworkUuid, notFoundSensitivityUuid, ComputationType.NON_EVACUATED_ENERGY_ANALYSIS); + assertNotNull(networkModificationTreeService.getComputationResultUuid(modificationNodeUuid, rootNetworkUuid, ComputationType.NON_EVACUATED_ENERGY_ANALYSIS)); + assertEquals(notFoundSensitivityUuid, networkModificationTreeService.getComputationResultUuid(modificationNodeUuid, rootNetworkUuid, ComputationType.NON_EVACUATED_ENERGY_ANALYSIS)); wireMock.stubFor(WireMock.get(WireMock.urlPathMatching("/v1/non-evacuated-energy/results/" + notFoundSensitivityUuid)) .willReturn(WireMock.notFound())); @@ -399,14 +400,15 @@ void testGetSensitivityNonEvacuatedEnergyResultWithWrongId() throws Exception { void testResetUuidResultWhenNonEvacuatedEnergyFailed() throws Exception { UUID resultUuid = UUID.randomUUID(); StudyEntity studyEntity = insertDummyStudy(UUID.randomUUID(), UUID.randomUUID()); + UUID rootNetworkUuid = studyEntity.getFirstRootNetwork().getId(); RootNode rootNode = networkModificationTreeService.getStudyTree(studyEntity.getId()); NetworkModificationNode modificationNode = createNetworkModificationNode(studyEntity.getId(), rootNode.getId(), UUID.randomUUID(), VARIANT_ID, "node 1"); - String resultUuidJson = objectMapper.writeValueAsString(new NodeReceiver(modificationNode.getId())); + String resultUuidJson = objectMapper.writeValueAsString(new NodeReceiver(modificationNode.getId(), rootNetworkUuid)); // Set an uuid result in the database - networkModificationTreeService.updateComputationResultUuid(modificationNode.getId(), resultUuid, ComputationType.NON_EVACUATED_ENERGY_ANALYSIS); - assertTrue(networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), ComputationType.NON_EVACUATED_ENERGY_ANALYSIS).isPresent()); - assertEquals(resultUuid, networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), ComputationType.NON_EVACUATED_ENERGY_ANALYSIS).get()); + networkModificationTreeService.updateComputationResultUuid(modificationNode.getId(), rootNetworkUuid, resultUuid, ComputationType.NON_EVACUATED_ENERGY_ANALYSIS); + assertNotNull(networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), rootNetworkUuid, ComputationType.NON_EVACUATED_ENERGY_ANALYSIS)); + assertEquals(resultUuid, networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), rootNetworkUuid, ComputationType.NON_EVACUATED_ENERGY_ANALYSIS)); StudyService studyService = Mockito.mock(StudyService.class); doAnswer(invocation -> { @@ -419,7 +421,7 @@ void testResetUuidResultWhenNonEvacuatedEnergyFailed() throws Exception { assertEquals(studyEntity.getId(), message.getHeaders().get(NotificationService.HEADER_STUDY_UUID)); String updateType = (String) message.getHeaders().get(NotificationService.HEADER_UPDATE_TYPE); assertEquals(NotificationService.UPDATE_TYPE_NON_EVACUATED_ENERGY_FAILED, updateType); - assertTrue(networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), ComputationType.NON_EVACUATED_ENERGY_ANALYSIS).isEmpty()); + assertNull(networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), rootNetworkUuid, ComputationType.NON_EVACUATED_ENERGY_ANALYSIS)); } @Test @@ -482,19 +484,19 @@ void testNonEvacuatedEnergyFailedForNotification(final MockWebServer server) thr private StudyEntity insertDummyStudy(UUID networkUuid, UUID caseUuid) { NonEvacuatedEnergyParametersEntity nonEvacuatedEnergyParametersEntity = NonEvacuatedEnergyService.toEntity(NonEvacuatedEnergyService.getDefaultNonEvacuatedEnergyParametersInfos()); - StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, caseUuid, "", UUID.randomUUID(), null, null, null, + StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, "netId", caseUuid, "", "", null, UUID.randomUUID(), null, null, null, nonEvacuatedEnergyParametersEntity); var study = studyRepository.save(studyEntity); - networkModificationTreeService.createRoot(studyEntity, null); + networkModificationTreeService.createRoot(studyEntity); return study; } private StudyEntity insertDummyStudyWithSpecificParams(UUID networkUuid, UUID caseUuid) { NonEvacuatedEnergyParametersEntity nonEvacuatedEnergyParametersEntity = NonEvacuatedEnergyService.toEntity(NonEvacuatedEnergyService.getDefaultNonEvacuatedEnergyParametersInfos()); - StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, caseUuid, "", UUID.randomUUID(), null, null, null, + StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, "netId", caseUuid, "", "", null, UUID.randomUUID(), null, null, null, nonEvacuatedEnergyParametersEntity); var study = studyRepository.save(studyEntity); - networkModificationTreeService.createRoot(studyEntity, null); + networkModificationTreeService.createRoot(studyEntity); return study; } diff --git a/src/test/java/org/gridsuite/study/server/RemoteServicesInspectorEndpointTest.java b/src/test/java/org/gridsuite/study/server/RemoteServicesInspectorEndpointTest.java index 5bc9161cb..30d23ae16 100644 --- a/src/test/java/org/gridsuite/study/server/RemoteServicesInspectorEndpointTest.java +++ b/src/test/java/org/gridsuite/study/server/RemoteServicesInspectorEndpointTest.java @@ -13,9 +13,12 @@ import org.gridsuite.study.server.dto.ServiceStatusInfos; import org.gridsuite.study.server.dto.ServiceStatusInfos.ServiceStatus; import org.gridsuite.study.server.exception.PartialResultException; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkNodeInfoRepository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkRepository; import org.gridsuite.study.server.service.FrontService; import org.gridsuite.study.server.service.NetworkModificationTreeService; import org.gridsuite.study.server.service.RemoteServicesInspector; +import org.gridsuite.study.server.service.RootNetworkService; import org.gridsuite.study.server.service.client.RemoteServiceName; import org.gridsuite.study.server.utils.elasticsearch.DisableElasticsearch; import org.junit.jupiter.api.MethodOrderer; @@ -48,6 +51,9 @@ @DisableCloudStream @DisableJpa @MockBean(NetworkModificationTreeService.class) //strange error during bean initialization +@MockBean(RootNetworkService.class) //TODO check with tristan why it is needed +@MockBean(RootNetworkRepository.class) +@MockBean(RootNetworkNodeInfoRepository.class) @SpringBootTest(classes = StudyApplication.class) @ExtendWith({MockitoExtension.class}) @TestMethodOrder(MethodOrderer.MethodName.class) diff --git a/src/test/java/org/gridsuite/study/server/SecurityAnalysisTest.java b/src/test/java/org/gridsuite/study/server/SecurityAnalysisTest.java index 9668aa17c..38113bbfe 100644 --- a/src/test/java/org/gridsuite/study/server/SecurityAnalysisTest.java +++ b/src/test/java/org/gridsuite/study/server/SecurityAnalysisTest.java @@ -25,7 +25,7 @@ import org.gridsuite.study.server.notification.NotificationService; import org.gridsuite.study.server.repository.StudyEntity; import org.gridsuite.study.server.repository.StudyRepository; -import org.gridsuite.study.server.repository.networkmodificationtree.NetworkModificationNodeInfoRepository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkNodeInfoRepository; import org.gridsuite.study.server.repository.nonevacuatedenergy.NonEvacuatedEnergyParametersEntity; import org.gridsuite.study.server.service.*; import org.gridsuite.study.server.service.securityanalysis.SecurityAnalysisResultType; @@ -149,7 +149,7 @@ class SecurityAnalysisTest { private StudyRepository studyRepository; @Autowired - private NetworkModificationNodeInfoRepository networkModificationNodeInfoRepository; + private RootNetworkNodeInfoRepository rootNetworkNodeInfoRepository; @Autowired private ReportService reportService; @@ -185,7 +185,7 @@ public MockResponse dispatch(RecordedRequest request) { String resultUuid = path.matches(".*variantId=" + VARIANT_ID_3 + ".*") ? SECURITY_ANALYSIS_OTHER_NODE_RESULT_UUID : SECURITY_ANALYSIS_RESULT_UUID; input.send(MessageBuilder.withPayload("") .setHeader("resultUuid", resultUuid) - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .build(), saResultDestination); return new MockResponse(200, Headers.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE), "\"" + resultUuid + "\""); } else if (path.matches("/v1/results/" + SECURITY_ANALYSIS_RESULT_UUID + "/limit-types") @@ -215,7 +215,7 @@ public MockResponse dispatch(RecordedRequest request) { String resultUuid = path.matches(".*variantId=" + VARIANT_ID_3 + ".*") ? SECURITY_ANALYSIS_OTHER_NODE_RESULT_UUID : SECURITY_ANALYSIS_RESULT_UUID; input.send(MessageBuilder.withPayload("") .setHeader("resultUuid", resultUuid) - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .build(), saStoppedDestination); return new MockResponse(200); } else if (path.matches("/v1/contingency-lists/" + CONTINGENCY_LIST_NAME + "/export\\?networkUuid=" + NETWORK_UUID_STRING) @@ -234,7 +234,7 @@ public MockResponse dispatch(RecordedRequest request) { return new MockResponse(200, Headers.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE), SECURITY_ANALYSIS_STATUS_JSON); } else if (path.matches("/v1/networks/" + NETWORK_UUID_2_STRING + "/run-and-save.*")) { input.send(MessageBuilder.withPayload("") - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .build(), saFailedDestination); return new MockResponse(200, Headers.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE), "\"" + SECURITY_ANALYSIS_ERROR_NODE_RESULT_UUID + "\""); } else if (path.matches("/v1/networks/" + NETWORK_UUID_3_STRING + "/run-and-save.*")) { @@ -324,7 +324,7 @@ void testSecurityAnalysis(final MockWebServer server) throws Exception { assertTrue(TestUtils.getRequestsDone(1, server).stream().anyMatch(r -> r.matches("/v1/supervision/results-count"))); //Delete Security analysis results - assertEquals(1, networkModificationNodeInfoRepository.findAllBySecurityAnalysisResultUuidNotNull().size()); + assertEquals(1, rootNetworkNodeInfoRepository.findAllBySecurityAnalysisResultUuidNotNull().size()); mockMvc.perform(delete("/v1/supervision/computation/results") .queryParam("type", SECURITY_ANALYSIS.toString()) .queryParam("dryRun", "false")) @@ -333,31 +333,32 @@ void testSecurityAnalysis(final MockWebServer server) throws Exception { var requests = TestUtils.getRequestsDone(2, server); assertTrue(requests.contains("/v1/results")); assertTrue(requests.stream().anyMatch(r -> r.matches("/v1/reports"))); - assertEquals(0, networkModificationNodeInfoRepository.findAllBySecurityAnalysisResultUuidNotNull().size()); + assertEquals(0, rootNetworkNodeInfoRepository.findAllBySecurityAnalysisResultUuidNotNull().size()); } @Test void testResetUuidResultWhenSAFailed() throws Exception { UUID resultUuid = UUID.randomUUID(); StudyEntity studyEntity = insertDummyStudy(UUID.randomUUID(), UUID.randomUUID()); + UUID rootNetworkUuid = studyEntity.getFirstRootNetwork().getId(); RootNode rootNode = networkModificationTreeService.getStudyTree(studyEntity.getId()); NetworkModificationNode modificationNode = createNetworkModificationNode(studyEntity.getId(), rootNode.getId(), UUID.randomUUID(), VARIANT_ID, "node 1"); - String resultUuidJson = objectMapper.writeValueAsString(new NodeReceiver(modificationNode.getId())); + String resultUuidJson = objectMapper.writeValueAsString(new NodeReceiver(modificationNode.getId(), rootNetworkUuid)); // Set an uuid result in the database - networkModificationTreeService.updateComputationResultUuid(modificationNode.getId(), resultUuid, SECURITY_ANALYSIS); - assertTrue(networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), SECURITY_ANALYSIS).isPresent()); - assertEquals(resultUuid, networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), SECURITY_ANALYSIS).get()); + networkModificationTreeService.updateComputationResultUuid(modificationNode.getId(), rootNetworkUuid, resultUuid, SECURITY_ANALYSIS); + assertNotNull(networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), rootNetworkUuid, SECURITY_ANALYSIS)); + assertEquals(resultUuid, networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), rootNetworkUuid, SECURITY_ANALYSIS)); StudyService studyService = Mockito.mock(StudyService.class); doAnswer(invocation -> { input.send(MessageBuilder.withPayload("").setHeader(HEADER_RECEIVER, resultUuidJson).build(), saFailedDestination); return resultUuid; - }).when(studyService).runSecurityAnalysis(any(), any(), any(), any()); - studyService.runSecurityAnalysis(studyEntity.getId(), List.of(), modificationNode.getId(), ""); + }).when(studyService).runSecurityAnalysis(any(), any(), any(), any(), any()); + studyService.runSecurityAnalysis(studyEntity.getId(), List.of(), modificationNode.getId(), rootNetworkUuid, ""); // Test reset uuid result in the database - assertTrue(networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), SECURITY_ANALYSIS).isEmpty()); + assertNull(networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), rootNetworkUuid, SECURITY_ANALYSIS)); Message message = output.receive(TIMEOUT, studyUpdateDestination); assertEquals(studyEntity.getId(), message.getHeaders().get(NotificationService.HEADER_STUDY_UUID)); @@ -527,11 +528,11 @@ private void testSecurityAnalysisWithNodeUuid(final MockWebServer server, UUID s private StudyEntity insertDummyStudy(UUID networkUuid, UUID caseUuid) { NonEvacuatedEnergyParametersEntity defaultNonEvacuatedEnergyParametersEntity = NonEvacuatedEnergyService.toEntity(NonEvacuatedEnergyService.getDefaultNonEvacuatedEnergyParametersInfos()); - StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, caseUuid, "", + StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, "netId", caseUuid, "", "", null, UUID.randomUUID(), null, null, null, defaultNonEvacuatedEnergyParametersEntity); var study = studyRepository.save(studyEntity); - networkModificationTreeService.createRoot(studyEntity, null); + networkModificationTreeService.createRoot(studyEntity); return study; } diff --git a/src/test/java/org/gridsuite/study/server/SensitivityAnalysisTest.java b/src/test/java/org/gridsuite/study/server/SensitivityAnalysisTest.java index 5563e2a5d..ce3428890 100644 --- a/src/test/java/org/gridsuite/study/server/SensitivityAnalysisTest.java +++ b/src/test/java/org/gridsuite/study/server/SensitivityAnalysisTest.java @@ -29,7 +29,7 @@ import org.gridsuite.study.server.notification.NotificationService; import org.gridsuite.study.server.repository.StudyEntity; import org.gridsuite.study.server.repository.StudyRepository; -import org.gridsuite.study.server.repository.networkmodificationtree.NetworkModificationNodeInfoRepository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkNodeInfoRepository; import org.gridsuite.study.server.repository.nonevacuatedenergy.NonEvacuatedEnergyParametersEntity; import org.gridsuite.study.server.service.*; import org.gridsuite.study.server.utils.SendInput; @@ -144,7 +144,7 @@ class SensitivityAnalysisTest { private StudyRepository studyRepository; @Autowired - private NetworkModificationNodeInfoRepository networkModificationNodeInfoRepository; + private RootNetworkNodeInfoRepository rootNetworkNodeInfoRepository; @Autowired private ReportService reportService; @@ -192,12 +192,12 @@ public MockResponse dispatch(RecordedRequest request) { input.send(MessageBuilder.withPayload("") .setHeader("resultUuid", resultUuid) .setHeader(HEADER_USER_ID, "testUserId") - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .build(), SENSITIVITY_ANALYSIS_RESULT_DESTINATION); return new MockResponse(200, Headers.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE), "\"" + resultUuid + "\""); } else if (path.matches("/v1/networks/" + NETWORK_UUID_2_STRING + "/run-and-save.*")) { input.send(MessageBuilder.withPayload("") - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .setHeader(HEADER_USER_ID, "testUserId") .build(), SENSITIVITY_ANALYSIS_FAILED_DESTINATION); return new MockResponse(200, Headers.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE), "\"" + SENSITIVITY_ANALYSIS_ERROR_NODE_RESULT_UUID + "\""); @@ -211,7 +211,7 @@ public MockResponse dispatch(RecordedRequest request) { String resultUuid = path.matches(".*variantId=" + VARIANT_ID_3 + ".*") ? SENSITIVITY_ANALYSIS_OTHER_NODE_RESULT_UUID : SENSITIVITY_ANALYSIS_RESULT_UUID; input.send(MessageBuilder.withPayload("") .setHeader("resultUuid", resultUuid) - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .build(), SENSITIVITY_ANALYSIS_STOPPED_DESTINATION); return new MockResponse(200); } else if (path.matches("/v1/results/" + SENSITIVITY_ANALYSIS_OTHER_NODE_RESULT_UUID)) { @@ -387,7 +387,7 @@ void testSensitivityAnalysis(final MockWebServer server) throws Exception { assertTrue(TestUtils.getRequestsDone(1, server).stream().anyMatch(r -> r.matches("/v1/supervision/results-count"))); //Delete Sensitivity analysis results - assertEquals(1, networkModificationNodeInfoRepository.findAllBySensitivityAnalysisResultUuidNotNull().size()); + assertEquals(1, rootNetworkNodeInfoRepository.findAllBySensitivityAnalysisResultUuidNotNull().size()); mockMvc.perform(delete("/v1/supervision/computation/results") .queryParam("type", SENSITIVITY_ANALYSIS.toString()) .queryParam("dryRun", "false")) @@ -396,7 +396,7 @@ void testSensitivityAnalysis(final MockWebServer server) throws Exception { var requests = TestUtils.getRequestsDone(2, server); assertTrue(requests.contains("/v1/results")); assertTrue(requests.stream().anyMatch(r -> r.matches("/v1/reports"))); - assertEquals(0, networkModificationNodeInfoRepository.findAllBySensitivityAnalysisResultUuidNotNull().size()); + assertEquals(0, rootNetworkNodeInfoRepository.findAllBySensitivityAnalysisResultUuidNotNull().size()); String baseUrlWireMock = wireMock.baseUrl(); sensitivityAnalysisService.setSensitivityAnalysisServerBaseUri(baseUrlWireMock); @@ -423,6 +423,7 @@ void testSensitivityAnalysis(final MockWebServer server) throws Exception { @Test void testGetSensitivityResultWithWrongId() throws Exception { StudyEntity studyEntity = insertDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_UUID); + UUID rootNetworkUuid = studyEntity.getFirstRootNetwork().getId(); UUID notFoundSensitivityUuid = UUID.randomUUID(); UUID studyUuid = studyEntity.getId(); mockMvc.perform(get("/v1/studies/{studyUuid}/nodes/{nodeUuid}/sensitivity-analysis/result?selector={selector}", studyUuid, UUID.randomUUID(), FAKE_RESULT_JSON)) @@ -437,9 +438,9 @@ void testGetSensitivityResultWithWrongId() throws Exception { UUID rootNodeUuid = getRootNodeUuid(studyUuid); NetworkModificationNode modificationNode1 = createNetworkModificationNode(studyUuid, rootNodeUuid, UUID.randomUUID(), VARIANT_ID, "node 1"); UUID modificationNodeUuid = modificationNode1.getId(); - networkModificationTreeService.updateComputationResultUuid(modificationNodeUuid, notFoundSensitivityUuid, SENSITIVITY_ANALYSIS); - assertTrue(networkModificationTreeService.getComputationResultUuid(modificationNodeUuid, SENSITIVITY_ANALYSIS).isPresent()); - assertEquals(notFoundSensitivityUuid, networkModificationTreeService.getComputationResultUuid(modificationNodeUuid, SENSITIVITY_ANALYSIS).get()); + networkModificationTreeService.updateComputationResultUuid(modificationNodeUuid, rootNetworkUuid, notFoundSensitivityUuid, SENSITIVITY_ANALYSIS); + assertNotNull(networkModificationTreeService.getComputationResultUuid(modificationNodeUuid, rootNetworkUuid, SENSITIVITY_ANALYSIS)); + assertEquals(notFoundSensitivityUuid, networkModificationTreeService.getComputationResultUuid(modificationNodeUuid, rootNetworkUuid, SENSITIVITY_ANALYSIS)); wireMock.stubFor(WireMock.get(WireMock.urlPathMatching("/v1/results/" + notFoundSensitivityUuid)) .willReturn(WireMock.notFound())); @@ -458,14 +459,15 @@ void testGetSensitivityResultWithWrongId() throws Exception { void testResetUuidResultWhenSAFailed() throws Exception { UUID resultUuid = UUID.randomUUID(); StudyEntity studyEntity = insertDummyStudy(UUID.randomUUID(), UUID.randomUUID()); + UUID rootNetworkUuid = studyEntity.getFirstRootNetwork().getId(); RootNode rootNode = networkModificationTreeService.getStudyTree(studyEntity.getId()); NetworkModificationNode modificationNode = createNetworkModificationNode(studyEntity.getId(), rootNode.getId(), UUID.randomUUID(), VARIANT_ID, "node 1"); - String resultUuidJson = objectMapper.writeValueAsString(new NodeReceiver(modificationNode.getId())); + String resultUuidJson = objectMapper.writeValueAsString(new NodeReceiver(modificationNode.getId(), rootNetworkUuid)); // Set an uuid result in the database - networkModificationTreeService.updateComputationResultUuid(modificationNode.getId(), resultUuid, SENSITIVITY_ANALYSIS); - assertTrue(networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), SENSITIVITY_ANALYSIS).isPresent()); - assertEquals(resultUuid, networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), SENSITIVITY_ANALYSIS).get()); + networkModificationTreeService.updateComputationResultUuid(modificationNode.getId(), rootNetworkUuid, resultUuid, SENSITIVITY_ANALYSIS); + assertNotNull(networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), rootNetworkUuid, SENSITIVITY_ANALYSIS)); + assertEquals(resultUuid, networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), rootNetworkUuid, SENSITIVITY_ANALYSIS)); StudyService studyService = Mockito.mock(StudyService.class); doAnswer(invocation -> { @@ -475,7 +477,7 @@ void testResetUuidResultWhenSAFailed() throws Exception { studyService.runSensitivityAnalysis(studyEntity.getId(), modificationNode.getId(), "testUserId"); // Test reset uuid result in the database - assertTrue(networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), SENSITIVITY_ANALYSIS).isEmpty()); + assertNull(networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), rootNetworkUuid, SENSITIVITY_ANALYSIS)); Message message = output.receive(TIMEOUT, STUDY_UPDATE_DESTINATION); assertEquals(studyEntity.getId(), message.getHeaders().get(NotificationService.HEADER_STUDY_UUID)); @@ -537,10 +539,10 @@ void testSensitivityAnalysisFailedForNotification(final MockWebServer server) th private StudyEntity insertDummyStudy(UUID networkUuid, UUID caseUuid) { NonEvacuatedEnergyParametersEntity defaultNonEvacuatedEnergyParametersEntity = NonEvacuatedEnergyService.toEntity(NonEvacuatedEnergyService.getDefaultNonEvacuatedEnergyParametersInfos()); - StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, caseUuid, "", UUID.randomUUID(), null, null, SENSITIVITY_ANALYSIS_PARAMETERS_UUID, + StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, "netId", caseUuid, "", "", null, UUID.randomUUID(), null, null, SENSITIVITY_ANALYSIS_PARAMETERS_UUID, defaultNonEvacuatedEnergyParametersEntity); var study = studyRepository.save(studyEntity); - networkModificationTreeService.createRoot(studyEntity, null); + networkModificationTreeService.createRoot(studyEntity); return study; } @@ -603,8 +605,7 @@ void testSensitivityAnalysisParameters() throws Exception { .willReturn(WireMock.ok().withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).withBody(objectMapper.writeValueAsString(SENSITIVITY_ANALYSIS_PARAMETERS_UUID)))); // end mocking - StudyEntity studyEntity = insertDummyStudy(UUID.randomUUID(), UUID.randomUUID()); - UUID studyNameUserIdUuid = studyEntity.getId(); + UUID studyNameUserIdUuid = insertDummyStudy(UUID.randomUUID(), UUID.randomUUID()).getId(); assertNotNull(studyNameUserIdUuid); // Get sensitivity analysis parameters (on existing) @@ -620,8 +621,9 @@ void testSensitivityAnalysisParameters() throws Exception { wireMock.verify(WireMock.putRequestedFor(WireMock.urlPathEqualTo("/v1/parameters/" + SENSITIVITY_ANALYSIS_PARAMETERS_UUID))); // Get sensitivity analysis (not existing, so it will create default) - studyEntity.setSensitivityAnalysisParametersUuid(null); - studyRepository.save(studyEntity); + StudyEntity studyEntityToUpdate = studyRepository.findById(studyNameUserIdUuid).orElseThrow(() -> new StudyException(StudyException.Type.STUDY_NOT_FOUND)); + studyEntityToUpdate.setSensitivityAnalysisParametersUuid(null); + studyRepository.save(studyEntityToUpdate); mockMvc.perform(get("/v1/studies/{studyUuid}/sensitivity-analysis/parameters", studyNameUserIdUuid)).andExpectAll( status().isOk(), @@ -632,8 +634,8 @@ void testSensitivityAnalysisParameters() throws Exception { assertEquals(SENSITIVITY_ANALYSIS_PARAMETERS_UUID, studyRepository.findById(studyNameUserIdUuid).orElseThrow().getSensitivityAnalysisParametersUuid()); // Set sensitivity analysis parameters (will create) - studyEntity.setSensitivityAnalysisParametersUuid(null); - studyRepository.save(studyEntity); + studyEntityToUpdate.setSensitivityAnalysisParametersUuid(null); + studyRepository.save(studyEntityToUpdate); setParametersAndDoChecks(studyNameUserIdUuid, SENSITIVITY_ANALYSIS_UPDATED_PARAMETERS_JSON); diff --git a/src/test/java/org/gridsuite/study/server/ShortCircuitTest.java b/src/test/java/org/gridsuite/study/server/ShortCircuitTest.java index 141b7340b..50ae61538 100644 --- a/src/test/java/org/gridsuite/study/server/ShortCircuitTest.java +++ b/src/test/java/org/gridsuite/study/server/ShortCircuitTest.java @@ -25,7 +25,7 @@ import org.gridsuite.study.server.notification.NotificationService; import org.gridsuite.study.server.repository.StudyEntity; import org.gridsuite.study.server.repository.StudyRepository; -import org.gridsuite.study.server.repository.networkmodificationtree.NetworkModificationNodeInfoRepository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkNodeInfoRepository; import org.gridsuite.study.server.repository.nonevacuatedenergy.NonEvacuatedEnergyParametersEntity; import org.gridsuite.study.server.service.NetworkModificationTreeService; import org.gridsuite.study.server.service.NonEvacuatedEnergyService; @@ -137,7 +137,7 @@ class ShortCircuitTest implements WithAssertions { private StudyRepository studyRepository; @Autowired - private NetworkModificationNodeInfoRepository networkModificationNodeInfoRepository; + private RootNetworkNodeInfoRepository rootNetworkNodeInfoRepository; @Autowired private ReportService reportService; @@ -171,25 +171,25 @@ public MockResponse dispatch(RecordedRequest request) { if (path.matches("/v1/networks/" + NETWORK_UUID_STRING + "/run-and-save\\?receiver=.*&reportUuid=.*&reporterId=.*&busId=BUS_TEST_ID&variantId=" + VARIANT_ID_2)) { input.send(MessageBuilder.withPayload("") .setHeader("resultUuid", SHORT_CIRCUIT_ANALYSIS_RESULT_UUID) - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .setHeader("busId", "BUS_TEST_ID") .build(), shortCircuitAnalysisResultDestination); return new MockResponse(200, Headers.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE), shortCircuitAnalysisResultUuidStr); } else if (path.matches("/v1/networks/" + NETWORK_UUID_STRING + "/run-and-save\\?receiver=.*&reportUuid=.*&reporterId=.*&variantId=" + VARIANT_ID_2)) { input.send(MessageBuilder.withPayload("") .setHeader("resultUuid", SHORT_CIRCUIT_ANALYSIS_RESULT_UUID) - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .build(), shortCircuitAnalysisResultDestination); return new MockResponse(200, Headers.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE), shortCircuitAnalysisResultUuidStr); } else if (path.matches("/v1/networks/" + NETWORK_UUID_STRING_NOT_FOUND + "/run-and-save\\?receiver=.*&reportUuid=.*&reporterId=.*&variantId=" + VARIANT_ID_4)) { input.send(MessageBuilder.withPayload("") .setHeader("resultUuid", SHORT_CIRCUIT_ANALYSIS_RESULT_UUID_NOT_FOUND) - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .build(), shortCircuitAnalysisResultDestination); return new MockResponse(200, Headers.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE), shortCircuitAnalysisResultNotFoundUuidStr); } else if (path.matches("/v1/networks/" + NETWORK_UUID_STRING + "/run-and-save\\?receiver=.*&reportUuid=.*&reporterId=.*&variantId=" + VARIANT_ID)) { input.send(MessageBuilder.withPayload("") - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .build(), shortCircuitAnalysisFailedDestination); return new MockResponse(200, Headers.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE), shortCircuitAnalysisErrorResultUuidStr); } else if (path.matches("/v1/results/" + SHORT_CIRCUIT_ANALYSIS_RESULT_UUID + "\\?mode=FULL")) { @@ -213,7 +213,7 @@ public MockResponse dispatch(RecordedRequest request) { String resultUuid = path.matches(".*variantId=" + VARIANT_ID_2 + ".*") ? SHORT_CIRCUIT_ANALYSIS_OTHER_NODE_RESULT_UUID : SHORT_CIRCUIT_ANALYSIS_RESULT_UUID; input.send(MessageBuilder.withPayload("") .setHeader("resultUuid", resultUuid) - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .build(), shortCircuitAnalysisStoppedDestination); return new MockResponse(200); } else if (path.matches("/v1/results")) { @@ -356,7 +356,7 @@ void testAllBusesShortCircuit(final MockWebServer server) throws Exception { // Delete Shortcircuit results // In short-circuit server there is no distinction between 1-bus and all-buses, so we remove all kinds of short-circuit - assertEquals(1, networkModificationNodeInfoRepository.findAllByShortCircuitAnalysisResultUuidNotNull().size()); + assertEquals(1, rootNetworkNodeInfoRepository.findAllByShortCircuitAnalysisResultUuidNotNull().size()); mockMvc.perform(delete("/v1/supervision/computation/results") .queryParam("type", ComputationType.SHORT_CIRCUIT.toString()) .queryParam("dryRun", "false")) @@ -365,7 +365,7 @@ void testAllBusesShortCircuit(final MockWebServer server) throws Exception { var requests = TestUtils.getRequestsDone(2, server); assertTrue(requests.contains("/v1/results")); assertTrue(requests.stream().anyMatch(r -> r.matches("/v1/reports"))); - assertEquals(0, networkModificationNodeInfoRepository.findAllByShortCircuitAnalysisResultUuidNotNull().size()); + assertEquals(0, rootNetworkNodeInfoRepository.findAllByShortCircuitAnalysisResultUuidNotNull().size()); } @Test @@ -513,7 +513,7 @@ void testOneBusShortCircuit(final MockWebServer server) throws Exception { assertTrue(TestUtils.getRequestsDone(1, server).stream().anyMatch(r -> r.matches("/v1/networks/" + NETWORK_UUID_STRING + "/run-and-save\\?receiver=.*&reportUuid=.*&reporterId=.*&variantId=" + VARIANT_ID_2))); - assertEquals(1, networkModificationNodeInfoRepository.findAllByOneBusShortCircuitAnalysisResultUuidNotNull().size()); + assertEquals(1, rootNetworkNodeInfoRepository.findAllByOneBusShortCircuitAnalysisResultUuidNotNull().size()); // get one bus short circuit result mockMvc.perform(get("/v1/studies/{studyUuid}/nodes/{nodeUuid}/shortcircuit/result", studyNameUserIdUuid, modificationNode3Uuid) @@ -560,31 +560,32 @@ void testOneBusShortCircuit(final MockWebServer server) throws Exception { var requests = TestUtils.getRequestsDone(2, server); assertTrue(requests.contains("/v1/results")); assertTrue(requests.stream().anyMatch(r -> r.matches("/v1/reports"))); - assertEquals(0, networkModificationNodeInfoRepository.findAllByOneBusShortCircuitAnalysisResultUuidNotNull().size()); + assertEquals(0, rootNetworkNodeInfoRepository.findAllByOneBusShortCircuitAnalysisResultUuidNotNull().size()); } @Test void testResetUuidResultWhenSCFailed() throws Exception { UUID resultUuid = UUID.randomUUID(); StudyEntity studyEntity = insertDummyStudy(UUID.randomUUID(), UUID.randomUUID()); + UUID rootNetworkUuid = studyEntity.getFirstRootNetwork().getId(); RootNode rootNode = networkModificationTreeService.getStudyTree(studyEntity.getId()); NetworkModificationNode modificationNode = createNetworkModificationNode(studyEntity.getId(), rootNode.getId(), UUID.randomUUID(), VARIANT_ID, "node 1"); - String resultUuidJson = objectMapper.writeValueAsString(new NodeReceiver(modificationNode.getId())); + String resultUuidJson = objectMapper.writeValueAsString(new NodeReceiver(modificationNode.getId(), rootNetworkUuid)); // Set an uuid result in the database - networkModificationTreeService.updateComputationResultUuid(modificationNode.getId(), resultUuid, ComputationType.SHORT_CIRCUIT); - assertTrue(networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), ComputationType.SHORT_CIRCUIT).isPresent()); - assertEquals(resultUuid, networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), ComputationType.SHORT_CIRCUIT).get()); + networkModificationTreeService.updateComputationResultUuid(modificationNode.getId(), rootNetworkUuid, resultUuid, ComputationType.SHORT_CIRCUIT); + assertNotNull(networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), rootNetworkUuid, ComputationType.SHORT_CIRCUIT)); + assertEquals(resultUuid, networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), rootNetworkUuid, ComputationType.SHORT_CIRCUIT)); StudyService studyService = Mockito.mock(StudyService.class); doAnswer(invocation -> { input.send(MessageBuilder.withPayload("").setHeader(HEADER_RECEIVER, resultUuidJson).build(), shortCircuitAnalysisFailedDestination); return resultUuid; - }).when(studyService).runShortCircuit(any(), any(), any(), any()); - studyService.runShortCircuit(studyEntity.getId(), modificationNode.getId(), Optional.empty(), "user_1"); + }).when(studyService).runShortCircuit(any(), any(), any(), any(), any()); + studyService.runShortCircuit(studyEntity.getId(), modificationNode.getId(), rootNetworkUuid, Optional.empty(), "user_1"); // Test reset uuid result in the database - assertTrue(networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), ComputationType.SHORT_CIRCUIT).isEmpty()); + assertNull(networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), rootNetworkUuid, ComputationType.SHORT_CIRCUIT)); Message message = output.receive(TIMEOUT, studyUpdateDestination); assertEquals(studyEntity.getId(), message.getHeaders().get(NotificationService.HEADER_STUDY_UUID)); @@ -698,11 +699,11 @@ void testInvalidateShortCircuitStatus(final MockWebServer server) throws Excepti private StudyEntity insertDummyStudy(UUID networkUuid, UUID caseUuid) { NonEvacuatedEnergyParametersEntity defaultNonEvacuatedEnergyParametersEntity = NonEvacuatedEnergyService.toEntity(NonEvacuatedEnergyService.getDefaultNonEvacuatedEnergyParametersInfos()); - StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, caseUuid, "", + StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, "netId", caseUuid, "", "", null, UUID.randomUUID(), null, null, null, defaultNonEvacuatedEnergyParametersEntity); var study = studyRepository.save(studyEntity); - networkModificationTreeService.createRoot(studyEntity, null); + networkModificationTreeService.createRoot(studyEntity); return study; } diff --git a/src/test/java/org/gridsuite/study/server/SingleLineDiagramTest.java b/src/test/java/org/gridsuite/study/server/SingleLineDiagramTest.java index bdf1cd0b3..22981ddaf 100644 --- a/src/test/java/org/gridsuite/study/server/SingleLineDiagramTest.java +++ b/src/test/java/org/gridsuite/study/server/SingleLineDiagramTest.java @@ -509,11 +509,11 @@ void testDiagramsVariantError() throws Exception { private StudyEntity insertDummyStudy(UUID networkUuid, UUID caseUuid) { NonEvacuatedEnergyParametersEntity defaultNonEvacuatedEnergyParametersEntity = NonEvacuatedEnergyService.toEntity(NonEvacuatedEnergyService.getDefaultNonEvacuatedEnergyParametersInfos()); - StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, caseUuid, "", + StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, "netId", caseUuid, "", "", null, LOADFLOW_PARAMETERS_UUID, null, null, null, null, defaultNonEvacuatedEnergyParametersEntity, false); var study = studyRepository.save(studyEntity); - networkModificationTreeService.createRoot(studyEntity, null); + networkModificationTreeService.createRoot(studyEntity); return study; } diff --git a/src/test/java/org/gridsuite/study/server/StateEstimationTest.java b/src/test/java/org/gridsuite/study/server/StateEstimationTest.java index 008ed07b9..81aac1cf4 100644 --- a/src/test/java/org/gridsuite/study/server/StateEstimationTest.java +++ b/src/test/java/org/gridsuite/study/server/StateEstimationTest.java @@ -25,6 +25,7 @@ import org.gridsuite.study.server.notification.NotificationService; import org.gridsuite.study.server.repository.StudyEntity; import org.gridsuite.study.server.repository.StudyRepository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkNodeInfoRepository; import org.gridsuite.study.server.repository.networkmodificationtree.NetworkModificationNodeInfoRepository; import org.gridsuite.study.server.repository.nonevacuatedenergy.NonEvacuatedEnergyParametersEntity; import org.gridsuite.study.server.service.*; @@ -121,6 +122,8 @@ class StateEstimationTest { private ReportService reportService; @Autowired private NetworkModificationNodeInfoRepository networkModificationNodeInfoRepository; + @Autowired + private RootNetworkNodeInfoRepository rootNetworkNodeInfoRepository; @AllArgsConstructor private static class StudyNodeIds { @@ -153,13 +156,13 @@ public MockResponse dispatch(RecordedRequest request) { // estim with success input.send(MessageBuilder.withPayload("") .setHeader("resultUuid", STATE_ESTIMATION_RESULT_UUID) - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .build(), ESTIM_RESULT_JSON_DESTINATION); return new MockResponse(200, Headers.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE), estimResultUuidStr); } else if (path.matches("/v1/networks/" + NETWORK_UUID_STRING + "/run-and-save\\?reportUuid=.*&reporterId=.*&reportType=StateEstimation&variantId=" + VARIANT_ID_2 + "&receiver=.*")) { // estim with failure input.send(MessageBuilder.withPayload("") - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .build(), ESTIM_FAILED_DESTINATION); return new MockResponse(200, Headers.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE), estimErrorResultUuidStr); } else if (path.matches("/v1/results/" + STATE_ESTIMATION_RESULT_UUID)) { @@ -169,7 +172,7 @@ public MockResponse dispatch(RecordedRequest request) { } else if (path.matches("/v1/results/" + STATE_ESTIMATION_RESULT_UUID + "/stop.*")) { input.send(MessageBuilder.withPayload("") .setHeader("resultUuid", STATE_ESTIMATION_RESULT_UUID) - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .build(), ESTIM_STOPPED_DESTINATION); return new MockResponse(200); } else if (path.matches("/v1/supervision/results-count")) { @@ -204,11 +207,11 @@ private void checkUpdateModelStatusMessagesReceived(UUID studyUuid, String updat private StudyNodeIds createStudyAndNode(String variantId, String nodeName) throws Exception { NonEvacuatedEnergyParametersEntity defaultNonEvacuatedEnergyParametersEntity = NonEvacuatedEnergyService.toEntity(NonEvacuatedEnergyService.getDefaultNonEvacuatedEnergyParametersInfos()); // create a study - StudyEntity studyEntity = TestUtils.createDummyStudy(UUID.fromString(NETWORK_UUID_STRING), CASE_LOADFLOW_UUID, "", + StudyEntity studyEntity = TestUtils.createDummyStudy(UUID.fromString(NETWORK_UUID_STRING), "netId", CASE_LOADFLOW_UUID, "", "", null, LOADFLOW_PARAMETERS_UUID, null, null, null, defaultNonEvacuatedEnergyParametersEntity); studyRepository.save(studyEntity); - networkModificationTreeService.createRoot(studyEntity, null); + networkModificationTreeService.createRoot(studyEntity); // with a node UUID studyUuid = studyEntity.getId(); UUID rootNodeUuid = getRootNode(studyUuid).getId(); @@ -294,7 +297,7 @@ void testResultsDeletion(final MockWebServer server) throws Exception { runEstim(server, ids); // we have one Estim result - assertEquals(1, networkModificationNodeInfoRepository.findAllByStateEstimationResultUuidNotNull().size()); + assertEquals(1, rootNetworkNodeInfoRepository.findAllByStateEstimationResultUuidNotNull().size()); // supervision deletion result, with dry-mode (only count) mockMvc.perform(delete("/v1/supervision/computation/results") @@ -312,7 +315,7 @@ void testResultsDeletion(final MockWebServer server) throws Exception { assertTrue(requests.contains("/v1/results")); assertTrue(requests.stream().anyMatch(r -> r.matches("/v1/reports"))); // no more result - assertEquals(0, networkModificationNodeInfoRepository.findAllByLoadFlowResultUuidNotNull().size()); + assertEquals(0, rootNetworkNodeInfoRepository.findAllByLoadFlowResultUuidNotNull().size()); } @Test diff --git a/src/test/java/org/gridsuite/study/server/StudyControllerDynamicSimulationTest.java b/src/test/java/org/gridsuite/study/server/StudyControllerDynamicSimulationTest.java index 73d77f979..af676e6d5 100644 --- a/src/test/java/org/gridsuite/study/server/StudyControllerDynamicSimulationTest.java +++ b/src/test/java/org/gridsuite/study/server/StudyControllerDynamicSimulationTest.java @@ -29,8 +29,11 @@ import org.gridsuite.study.server.notification.NotificationService; import org.gridsuite.study.server.repository.StudyEntity; import org.gridsuite.study.server.repository.StudyRepository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkEntity; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkRepository; import org.gridsuite.study.server.service.LoadFlowService; import org.gridsuite.study.server.service.NetworkModificationTreeService; +import org.gridsuite.study.server.service.StudyService; import org.gridsuite.study.server.service.client.util.UrlUtil; import org.gridsuite.study.server.service.dynamicsimulation.DynamicSimulationService; import org.gridsuite.study.server.utils.PropertyType; @@ -38,6 +41,7 @@ import org.gridsuite.study.server.utils.elasticsearch.DisableElasticsearch; import org.json.JSONObject; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mockito; import org.slf4j.Logger; @@ -132,7 +136,9 @@ class StudyControllerDynamicSimulationTest { private static final UUID STUDY_UUID = UUID.randomUUID(); private static final UUID NETWORK_UUID = UUID.randomUUID(); private static final UUID NODE_UUID = UUID.randomUUID(); + public static final UUID ROOTNETWORK_UUID = UUID.randomUUID(); private static final UUID NODE_NOT_DONE_UUID = UUID.randomUUID(); + private static final UUID ROOTNETWORK_NOT_DONE_UUID = UUID.randomUUID(); private static final UUID NODE_NOT_RUN_UUID = UUID.randomUUID(); private static final UUID RESULT_UUID = UUID.randomUUID(); @@ -160,6 +166,12 @@ class StudyControllerDynamicSimulationTest { @Autowired private NetworkModificationTreeService networkModificationTreeService; + @Autowired + private RootNetworkRepository rootNetworkRepository; + + @SpyBean + StudyService studyService; + @MockBean private LoadFlowService loadFlowService; @@ -182,6 +194,11 @@ class StudyControllerDynamicSimulationTest { private static final String DS_STOPPED_DESTINATION = "ds.stopped"; private static final String DS_FAILED_DESTINATION = "ds.failed"; + @BeforeEach + public void setup() { + Mockito.doReturn(ROOTNETWORK_UUID).when(studyService).getStudyFirstRootNetworkUuid(STUDY_UUID); + } + @AfterEach void tearDown() { studyRepository.findAll().forEach(s -> networkModificationTreeService.doDeleteTree(s.getId())); @@ -200,9 +217,9 @@ private RootNode getRootNode(UUID study) throws Exception { } private StudyEntity insertDummyStudy(UUID networkUuid, UUID caseUuid) { - StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, caseUuid, "", UUID.randomUUID(), null, null, null, null); + StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, "netId", caseUuid, "", "", UUID.randomUUID(), UUID.randomUUID(), null, null, null, null); var study = studyRepository.save(studyEntity); - networkModificationTreeService.createRoot(studyEntity, null); + networkModificationTreeService.createRoot(studyEntity); return study; } @@ -243,9 +260,10 @@ void testRunDynamicSimulationGivenRegularNodeAndFailed() throws Exception { UUID rootNodeUuid = getRootNode(studyUuid).getId(); NetworkModificationNode modificationNode1 = createNetworkModificationNode(studyUuid, rootNodeUuid, UUID.randomUUID(), VARIANT_ID, "node 1"); UUID modificationNode1Uuid = modificationNode1.getId(); - when(loadFlowService.getLoadFlowStatus(any())).thenReturn(LoadFlowStatus.CONVERGED.name()); + RootNetworkEntity rootNetworkEntity = rootNetworkRepository.findAllByStudyId(studyUuid).stream().findFirst().orElseThrow(() -> new StudyException(StudyException.Type.ROOTNETWORK_NOT_FOUND)); + when(loadFlowService.getLoadFlowStatus(any(), any())).thenReturn(LoadFlowStatus.CONVERGED.name()); // setup DynamicSimulationService mock - Mockito.doAnswer(invocation -> RESULT_UUID).when(dynamicSimulationService).runDynamicSimulation(any(), eq(studyUuid), eq(modificationNode1Uuid), any(), any(), any()); + Mockito.doAnswer(invocation -> RESULT_UUID).when(dynamicSimulationService).runDynamicSimulation(any(), eq(studyUuid), eq(modificationNode1Uuid), eq(rootNetworkEntity.getId()), any(), any(), any()); // --- call endpoint to be tested --- // // run on a regular node which allows a run @@ -263,12 +281,12 @@ void testRunDynamicSimulationGivenRegularNodeAndFailed() throws Exception { .containsEntry(NotificationService.HEADER_STUDY_UUID, studyUuid) .containsEntry(NotificationService.HEADER_UPDATE_TYPE, NotificationService.UPDATE_TYPE_DYNAMIC_SIMULATION_STATUS); // resultUuid must be present in database at this moment - UUID actualResultUuid = networkModificationTreeService.getComputationResultUuid(modificationNode1Uuid, ComputationType.DYNAMIC_SIMULATION).get(); + UUID actualResultUuid = networkModificationTreeService.getComputationResultUuid(modificationNode1Uuid, rootNetworkEntity.getId(), ComputationType.DYNAMIC_SIMULATION); LOGGER.info("Actual result uuid in the database = {}", actualResultUuid); assertThat(actualResultUuid).isEqualTo(RESULT_UUID); // mock the notification from dynamic-simulation server in case of failed - String receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(modificationNode1Uuid)), + String receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(modificationNode1Uuid, rootNetworkEntity.getId())), StandardCharsets.UTF_8); input.send(MessageBuilder.withPayload("") .setHeader("resultUuid", RESULT_UUID.toString()) @@ -283,7 +301,7 @@ void testRunDynamicSimulationGivenRegularNodeAndFailed() throws Exception { .containsEntry(NotificationService.HEADER_STUDY_UUID, studyUuid) .containsEntry(NotificationService.HEADER_UPDATE_TYPE, NotificationService.UPDATE_TYPE_DYNAMIC_SIMULATION_FAILED); // resultUuid must be empty in database at this moment - assertThat(networkModificationTreeService.getComputationResultUuid(modificationNode1Uuid, ComputationType.DYNAMIC_SIMULATION)).isEmpty(); + assertThat(networkModificationTreeService.getComputationResultUuid(modificationNode1Uuid, rootNetworkEntity.getId(), ComputationType.DYNAMIC_SIMULATION)).isNull(); } @Test @@ -309,9 +327,10 @@ void testRunDynamicSimulationGivenRegularNode() throws Exception { UUID rootNodeUuid = getRootNode(studyUuid).getId(); NetworkModificationNode modificationNode1 = createNetworkModificationNode(studyUuid, rootNodeUuid, UUID.randomUUID(), VARIANT_ID, "node 1"); UUID modificationNode1Uuid = modificationNode1.getId(); - when(loadFlowService.getLoadFlowStatus(any())).thenReturn(LoadFlowStatus.CONVERGED.name()); + RootNetworkEntity rootNetworkEntity = rootNetworkRepository.findAllByStudyId(studyUuid).stream().findFirst().orElseThrow(() -> new StudyException(StudyException.Type.ROOTNETWORK_NOT_FOUND)); + when(loadFlowService.getLoadFlowStatus(any(), any())).thenReturn(LoadFlowStatus.CONVERGED.name()); // setup DynamicSimulationService mock - Mockito.doAnswer(invocation -> RESULT_UUID).when(dynamicSimulationService).runDynamicSimulation(any(), eq(studyUuid), eq(modificationNode1Uuid), any(), any(), any()); + Mockito.doAnswer(invocation -> RESULT_UUID).when(dynamicSimulationService).runDynamicSimulation(any(), eq(studyUuid), eq(modificationNode1Uuid), eq(rootNetworkEntity.getId()), any(), any(), any()); MvcResult result; // --- call endpoint to be tested --- // @@ -330,12 +349,12 @@ void testRunDynamicSimulationGivenRegularNode() throws Exception { .containsEntry(NotificationService.HEADER_STUDY_UUID, studyUuid) .containsEntry(NotificationService.HEADER_UPDATE_TYPE, NotificationService.UPDATE_TYPE_DYNAMIC_SIMULATION_STATUS); // resultUuid must be present in database at this moment - UUID actualResultUuid = networkModificationTreeService.getComputationResultUuid(modificationNode1Uuid, ComputationType.DYNAMIC_SIMULATION).get(); + UUID actualResultUuid = networkModificationTreeService.getComputationResultUuid(modificationNode1Uuid, rootNetworkEntity.getId(), ComputationType.DYNAMIC_SIMULATION); LOGGER.info("Actual result uuid in the database = {}", actualResultUuid); assertThat(actualResultUuid).isEqualTo(RESULT_UUID); // mock the notification from dynamic-simulation server in case of having the result - String receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(modificationNode1Uuid)), + String receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(modificationNode1Uuid, rootNetworkEntity.getId())), StandardCharsets.UTF_8); input.send(MessageBuilder.withPayload("") .setHeader("resultUuid", RESULT_UUID.toString()) @@ -383,10 +402,11 @@ void testRunDynamicSimulationGivenRegularNodeAndStopped() throws Exception { UUID rootNodeUuid = getRootNode(studyUuid).getId(); NetworkModificationNode modificationNode1 = createNetworkModificationNode(studyUuid, rootNodeUuid, UUID.randomUUID(), VARIANT_ID, "node 1"); UUID modificationNode1Uuid = modificationNode1.getId(); + RootNetworkEntity rootNetworkEntity = rootNetworkRepository.findAllByStudyId(studyUuid).stream().findFirst().orElseThrow(() -> new StudyException(StudyException.Type.ROOTNETWORK_NOT_FOUND)); - when(loadFlowService.getLoadFlowStatus(any())).thenReturn(LoadFlowStatus.CONVERGED.name()); + when(loadFlowService.getLoadFlowStatus(any(), any())).thenReturn(LoadFlowStatus.CONVERGED.name()); // setup DynamicSimulationService mock - Mockito.doAnswer(invocation -> RESULT_UUID).when(dynamicSimulationService).runDynamicSimulation(any(), eq(studyUuid), eq(modificationNode1Uuid), any(), any(), any()); + Mockito.doAnswer(invocation -> RESULT_UUID).when(dynamicSimulationService).runDynamicSimulation(any(), eq(studyUuid), eq(modificationNode1Uuid), eq(rootNetworkEntity.getId()), any(), any(), any()); // --- call endpoint to be tested --- // // run on a regular node which allows a run @@ -404,12 +424,12 @@ void testRunDynamicSimulationGivenRegularNodeAndStopped() throws Exception { .containsEntry(NotificationService.HEADER_STUDY_UUID, studyUuid) .containsEntry(NotificationService.HEADER_UPDATE_TYPE, NotificationService.UPDATE_TYPE_DYNAMIC_SIMULATION_STATUS); // resultUuid must be present in database at this moment - UUID actualResultUuid = networkModificationTreeService.getComputationResultUuid(modificationNode1Uuid, ComputationType.DYNAMIC_SIMULATION).get(); + UUID actualResultUuid = networkModificationTreeService.getComputationResultUuid(modificationNode1Uuid, rootNetworkEntity.getId(), ComputationType.DYNAMIC_SIMULATION); LOGGER.info("Actual result uuid in the database = {}", actualResultUuid); assertThat(actualResultUuid).isEqualTo(RESULT_UUID); // mock the notification from dynamic-simulation server in case of stop - String receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(modificationNode1Uuid)), + String receiver = URLEncoder.encode(objectMapper.writeValueAsString(new NodeReceiver(modificationNode1Uuid, rootNetworkEntity.getId())), StandardCharsets.UTF_8); input.send(MessageBuilder.withPayload("") .setHeader("resultUuid", RESULT_UUID.toString()) @@ -428,7 +448,7 @@ void testRunDynamicSimulationGivenRegularNodeAndStopped() throws Exception { @Test void testGetDynamicSimulationTimeSeriesResultGivenNodeNotDone() throws Exception { // setup DynamicSimulationService mock - Mockito.doAnswer(invocation -> null).when(dynamicSimulationService).getTimeSeriesResult(NODE_NOT_DONE_UUID, null); + Mockito.doAnswer(invocation -> null).when(dynamicSimulationService).getTimeSeriesResult(NODE_NOT_DONE_UUID, ROOTNETWORK_NOT_DONE_UUID, null); // --- call endpoint to be tested --- // // get result from a node not yet done @@ -448,7 +468,7 @@ void testGetDynamicSimulationTimeSeriesResult() throws Exception { )); // setup DynamicSimulationService mock - Mockito.doAnswer(invocation -> timeSeries).when(dynamicSimulationService).getTimeSeriesResult(NODE_UUID, null); + Mockito.doAnswer(invocation -> timeSeries).when(dynamicSimulationService).getTimeSeriesResult(NODE_UUID, ROOTNETWORK_UUID, null); // --- call endpoint to be tested --- // // get result from a node done @@ -470,7 +490,7 @@ void testGetDynamicSimulationTimeSeriesResult() throws Exception { @Test void testGetDynamicSimulationTimelineResultGivenNodeNotDone() throws Exception { // setup DynamicSimulationService mock - Mockito.doAnswer(invocation -> null).when(dynamicSimulationService).getTimelineResult(NODE_NOT_DONE_UUID); + Mockito.doAnswer(invocation -> null).when(dynamicSimulationService).getTimelineResult(NODE_NOT_DONE_UUID, ROOTNETWORK_NOT_DONE_UUID); // --- call endpoint to be tested --- // // get result from a node not yet done @@ -490,12 +510,12 @@ void testGetDynamicSimulationTimelineResult() throws Exception { ); // setup DynamicSimulationService mock - Mockito.doAnswer(invocation -> timelineEventInfosList).when(dynamicSimulationService).getTimelineResult(NODE_UUID); + Mockito.doAnswer(invocation -> timelineEventInfosList).when(dynamicSimulationService).getTimelineResult(NODE_UUID, ROOTNETWORK_UUID); // --- call endpoint to be tested --- // // get result from a node done MvcResult result = studyClient.perform(get(STUDY_BASE_URL + DELIMITER + STUDY_DYNAMIC_SIMULATION_END_POINT_RESULT + DELIMITER + "timeline", - STUDY_UUID, NODE_UUID) + STUDY_UUID, NODE_UUID, ROOTNETWORK_UUID) .header(HEADER_USER_ID_NAME, HEADER_USER_ID_VALUE)) .andExpect(status().isOk()).andReturn(); @@ -509,7 +529,7 @@ void testGetDynamicSimulationTimelineResult() throws Exception { @Test void testGetDynamicSimulationStatusResultGivenNodeNotRun() throws Exception { // setup DynamicSimulationService mock - Mockito.doAnswer(invocation -> null).when(dynamicSimulationService).getStatus(NODE_NOT_RUN_UUID); + Mockito.doAnswer(invocation -> null).when(dynamicSimulationService).getStatus(NODE_NOT_RUN_UUID, ROOTNETWORK_NOT_DONE_UUID); // --- call endpoint to be tested --- // // get result from a node not yet run @@ -525,12 +545,12 @@ void testGetDynamicSimulationTimeSeriesMetadata() throws Exception { // timeseries metadata List timeSeriesMetadataInfosList = List.of(new TimeSeriesMetadataInfos(TIME_SERIES_NAME_1), new TimeSeriesMetadataInfos(TIME_SERIES_NAME_2)); - Mockito.doAnswer(invocation -> timeSeriesMetadataInfosList).when(dynamicSimulationService).getTimeSeriesMetadataList(NODE_UUID); + Mockito.doAnswer(invocation -> timeSeriesMetadataInfosList).when(dynamicSimulationService).getTimeSeriesMetadataList(NODE_UUID, ROOTNETWORK_UUID); // --- call endpoint to be tested --- // // get timeseries metadata from a node done MvcResult result = studyClient.perform(get(STUDY_BASE_URL + DELIMITER + STUDY_DYNAMIC_SIMULATION_END_POINT_RESULT + DELIMITER + "timeseries/metadata", - STUDY_UUID, NODE_UUID) + STUDY_UUID, NODE_UUID, ROOTNETWORK_UUID) .header(HEADER_USER_ID_NAME, HEADER_USER_ID_VALUE)) .andExpect(status().isOk()).andReturn(); @@ -546,12 +566,12 @@ void testGetDynamicSimulationTimeSeriesMetadata() throws Exception { @Test void testGetDynamicSimulationStatus() throws Exception { // setup DynamicSimulationService mock - Mockito.doAnswer(invocation -> DynamicSimulationStatus.DIVERGED).when(dynamicSimulationService).getStatus(NODE_UUID); + Mockito.doAnswer(invocation -> DynamicSimulationStatus.DIVERGED).when(dynamicSimulationService).getStatus(NODE_UUID, ROOTNETWORK_UUID); // --- call endpoint to be tested --- // // get status from a node done MvcResult result = studyClient.perform(get(STUDY_BASE_URL + DELIMITER + STUDY_DYNAMIC_SIMULATION_END_POINT_STATUS, - STUDY_UUID, NODE_UUID) + STUDY_UUID, NODE_UUID, ROOTNETWORK_UUID) .header(HEADER_USER_ID_NAME, HEADER_USER_ID_VALUE)) .andExpect(status().isOk()).andReturn(); DynamicSimulationStatus statusResult = objectMapper.readValue(result.getResponse().getContentAsString(), DynamicSimulationStatus.class); diff --git a/src/test/java/org/gridsuite/study/server/StudyServiceSearchTests.java b/src/test/java/org/gridsuite/study/server/StudyServiceSearchTests.java index a02c9edbb..cdd270e9d 100644 --- a/src/test/java/org/gridsuite/study/server/StudyServiceSearchTests.java +++ b/src/test/java/org/gridsuite/study/server/StudyServiceSearchTests.java @@ -12,8 +12,8 @@ import org.gridsuite.study.server.dto.elasticsearch.TombstonedEquipmentInfos; import org.gridsuite.study.server.elasticsearch.EquipmentInfosService; import org.gridsuite.study.server.service.NetworkModificationTreeService; -import org.gridsuite.study.server.service.NetworkService; import org.gridsuite.study.server.service.StudyService; +import org.gridsuite.study.server.service.RootNetworkService; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -38,12 +38,12 @@ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) class StudyServiceSearchTests { - private static final UUID STUDY_UUID = UUID.fromString("14526897-4b5d-11bd-b23e-17e46e4ef00d"); - private static final UUID NETWORK_UUID = UUID.randomUUID(); private static final UUID NODE_UUID = UUID.fromString("12345678-8cf0-11bd-b23e-10b96e4ef00d"); + private static final UUID ROOTNETWORK_UUID = UUID.fromString("2345679-8cf0-11bd-b23e-10b96e4ef00d"); + private static final UUID VARIANT_NODE_UUID = UUID.fromString("87654321-8cf0-11bd-b23e-10b96e4ef00d"); private static final UUID VARIANT_NODE_UUID_2 = UUID.fromString("cb8271ee-de4c-40f6-8cf1-f19936243612"); @@ -53,22 +53,22 @@ class StudyServiceSearchTests { @Autowired private EquipmentInfosService equipmentInfosService; - @MockBean - private NetworkService networkService; - @MockBean private NetworkModificationTreeService networkModificationTreeService; @Autowired private StudyService studyService; + @MockBean + private RootNetworkService rootNetworkService; + @BeforeEach - void setup() { - when(networkService.getNetworkUuid(STUDY_UUID)).thenReturn(NETWORK_UUID); - when(networkModificationTreeService.getVariantId(NODE_UUID)).thenReturn(VariantManagerConstants.INITIAL_VARIANT_ID); - when(networkModificationTreeService.getVariantId(VARIANT_NODE_UUID)).thenReturn(VARIANT_ID); - when(networkModificationTreeService.getVariantId(VARIANT_NODE_UUID_2)).thenReturn(VARIANT_ID_2); - when(networkModificationTreeService.doGetLastParentNodeBuiltUuid(VARIANT_NODE_UUID)).thenReturn(VARIANT_NODE_UUID); + public void setup() { + when(rootNetworkService.getNetworkUuid(ROOTNETWORK_UUID)).thenReturn(NETWORK_UUID); + when(networkModificationTreeService.getVariantId(NODE_UUID, ROOTNETWORK_UUID)).thenReturn(VariantManagerConstants.INITIAL_VARIANT_ID); + when(networkModificationTreeService.getVariantId(VARIANT_NODE_UUID, ROOTNETWORK_UUID)).thenReturn(VARIANT_ID); + when(networkModificationTreeService.getVariantId(VARIANT_NODE_UUID_2, ROOTNETWORK_UUID)).thenReturn(VARIANT_ID_2); + when(networkModificationTreeService.doGetLastParentNodeBuiltUuid(VARIANT_NODE_UUID, ROOTNETWORK_UUID)).thenReturn(VARIANT_NODE_UUID); } @AfterEach @@ -94,24 +94,24 @@ void searchEquipmentInfosMultiVariants() { // Search with node of initial variant Set hits = new HashSet<>(); - hits.addAll(studyService.searchEquipments(STUDY_UUID, NODE_UUID, "id_g1", EquipmentInfosService.FieldSelector.ID, null, false)); + hits.addAll(studyService.searchEquipments(NODE_UUID, ROOTNETWORK_UUID, "id_g1", EquipmentInfosService.FieldSelector.ID, null, false)); assertEquals(1, hits.size()); assertTrue(hits.contains(generatorInfos)); hits.clear(); - hits.addAll(studyService.searchEquipments(STUDY_UUID, NODE_UUID, "id_l", EquipmentInfosService.FieldSelector.ID, null, false)); + hits.addAll(studyService.searchEquipments(NODE_UUID, ROOTNETWORK_UUID, "id_l", EquipmentInfosService.FieldSelector.ID, null, false)); assertEquals(2, hits.size()); assertTrue(hits.contains(line1Infos)); assertTrue(hits.contains(line2Infos)); // Search with node of new variant hits.clear(); - hits.addAll(studyService.searchEquipments(STUDY_UUID, VARIANT_NODE_UUID, "id_g1", EquipmentInfosService.FieldSelector.ID, null, false)); + hits.addAll(studyService.searchEquipments(VARIANT_NODE_UUID, ROOTNETWORK_UUID, "id_g1", EquipmentInfosService.FieldSelector.ID, null, false)); assertEquals(1, hits.size()); assertTrue(hits.contains(generatorInfos)); hits.clear(); - hits.addAll(studyService.searchEquipments(STUDY_UUID, VARIANT_NODE_UUID, "id_l", EquipmentInfosService.FieldSelector.ID, null, false)); + hits.addAll(studyService.searchEquipments(VARIANT_NODE_UUID, ROOTNETWORK_UUID, "id_l", EquipmentInfosService.FieldSelector.ID, null, false)); assertEquals(2, hits.size()); assertTrue(hits.contains(line1Infos)); assertTrue(hits.contains(line2Infos)); @@ -124,12 +124,12 @@ void searchEquipmentInfosMultiVariants() { // Search new equipments with node of initial variant hits.clear(); - hits.addAll(studyService.searchEquipments(STUDY_UUID, NODE_UUID, "id_new", EquipmentInfosService.FieldSelector.ID, null, false)); + hits.addAll(studyService.searchEquipments(NODE_UUID, ROOTNETWORK_UUID, "id_new", EquipmentInfosService.FieldSelector.ID, null, false)); assertEquals(0, hits.size()); // Search all equipments with node of initial variant hits.clear(); - hits.addAll(studyService.searchEquipments(STUDY_UUID, NODE_UUID, "id_", EquipmentInfosService.FieldSelector.ID, null, false)); + hits.addAll(studyService.searchEquipments(NODE_UUID, ROOTNETWORK_UUID, "id_", EquipmentInfosService.FieldSelector.ID, null, false)); assertEquals(4, hits.size()); assertTrue(hits.contains(line1Infos)); assertTrue(hits.contains(line2Infos)); @@ -138,14 +138,14 @@ void searchEquipmentInfosMultiVariants() { // Search new equipments with node of new variant hits.clear(); - hits.addAll(studyService.searchEquipments(STUDY_UUID, VARIANT_NODE_UUID, "id_new", EquipmentInfosService.FieldSelector.ID, null, false)); + hits.addAll(studyService.searchEquipments(VARIANT_NODE_UUID, ROOTNETWORK_UUID, "id_new", EquipmentInfosService.FieldSelector.ID, null, false)); assertEquals(2, hits.size()); assertTrue(hits.contains(newGeneratorInfos)); assertTrue(hits.contains(newLineInfos)); // Search all equipments with node of new variant hits.clear(); - hits.addAll(studyService.searchEquipments(STUDY_UUID, VARIANT_NODE_UUID, "id_", EquipmentInfosService.FieldSelector.ID, null, false)); + hits.addAll(studyService.searchEquipments(VARIANT_NODE_UUID, ROOTNETWORK_UUID, "id_", EquipmentInfosService.FieldSelector.ID, null, false)); assertEquals(6, hits.size()); assertTrue(hits.contains(line1Infos)); assertTrue(hits.contains(line2Infos)); @@ -160,48 +160,48 @@ void searchEquipmentInfosMultiVariants() { // Search 2wt with node of initial variant hits.clear(); - hits.addAll(studyService.searchEquipments(STUDY_UUID, NODE_UUID, "id_tw1", EquipmentInfosService.FieldSelector.ID, null, false)); + hits.addAll(studyService.searchEquipments(NODE_UUID, ROOTNETWORK_UUID, "id_tw1", EquipmentInfosService.FieldSelector.ID, null, false)); assertEquals(1, hits.size()); assertTrue(hits.contains(twInfos)); // Search specific load with node of initial variant hits.clear(); - hits.addAll(studyService.searchEquipments(STUDY_UUID, NODE_UUID, "loadId1", EquipmentInfosService.FieldSelector.ID, "LOAD", false)); + hits.addAll(studyService.searchEquipments(NODE_UUID, ROOTNETWORK_UUID, "loadId1", EquipmentInfosService.FieldSelector.ID, "LOAD", false)); assertEquals(1, hits.size()); assertTrue(hits.contains(load1Infos)); // Search lines with node of initial variant hits.clear(); - hits.addAll(studyService.searchEquipments(STUDY_UUID, NODE_UUID, "id", EquipmentInfosService.FieldSelector.ID, "LINE", false)); + hits.addAll(studyService.searchEquipments(NODE_UUID, ROOTNETWORK_UUID, "id", EquipmentInfosService.FieldSelector.ID, "LINE", false)); assertEquals(2, hits.size()); assertTrue(hits.contains(line1Infos)); // Search lines with node of new variant hits.clear(); - hits.addAll(studyService.searchEquipments(STUDY_UUID, VARIANT_NODE_UUID, "id", EquipmentInfosService.FieldSelector.ID, "LINE", false)); + hits.addAll(studyService.searchEquipments(VARIANT_NODE_UUID, ROOTNETWORK_UUID, "id", EquipmentInfosService.FieldSelector.ID, "LINE", false)); assertEquals(3, hits.size()); assertTrue(hits.contains(newLineInfos)); // Search specific load with the wrong type -> expect no result hits.clear(); - hits.addAll(studyService.searchEquipments(STUDY_UUID, NODE_UUID, "loadId2", EquipmentInfosService.FieldSelector.ID, "LINE", false)); + hits.addAll(studyService.searchEquipments(NODE_UUID, ROOTNETWORK_UUID, "loadId2", EquipmentInfosService.FieldSelector.ID, "LINE", false)); assertEquals(0, hits.size()); // Search both loads hits.clear(); - hits.addAll(studyService.searchEquipments(STUDY_UUID, NODE_UUID, "loadId", EquipmentInfosService.FieldSelector.ID, "LOAD", false)); + hits.addAll(studyService.searchEquipments(NODE_UUID, ROOTNETWORK_UUID, "loadId", EquipmentInfosService.FieldSelector.ID, "LOAD", false)); assertEquals(2, hits.size()); assertTrue(hits.contains(load2Infos)); assertTrue(hits.contains(load1Infos)); // Search 2wt with node of new variant hits.clear(); - hits.addAll(studyService.searchEquipments(STUDY_UUID, VARIANT_NODE_UUID, "id_tw1", EquipmentInfosService.FieldSelector.ID, null, false)); + hits.addAll(studyService.searchEquipments(VARIANT_NODE_UUID, ROOTNETWORK_UUID, "id_tw1", EquipmentInfosService.FieldSelector.ID, null, false)); assertEquals(0, hits.size()); // Search all equipments with node of new variant hits.clear(); - hits.addAll(studyService.searchEquipments(STUDY_UUID, VARIANT_NODE_UUID, "id_", EquipmentInfosService.FieldSelector.ID, null, false)); + hits.addAll(studyService.searchEquipments(VARIANT_NODE_UUID, ROOTNETWORK_UUID, "id_", EquipmentInfosService.FieldSelector.ID, null, false)); assertEquals(5, hits.size()); assertTrue(hits.contains(line1Infos)); assertTrue(hits.contains(line2Infos)); @@ -211,7 +211,7 @@ void searchEquipmentInfosMultiVariants() { // Search all equipments with node of new variant hits.clear(); - hits.addAll(studyService.searchEquipments(STUDY_UUID, VARIANT_NODE_UUID, "id_", EquipmentInfosService.FieldSelector.ID, null, true)); + hits.addAll(studyService.searchEquipments(VARIANT_NODE_UUID, ROOTNETWORK_UUID, "id_", EquipmentInfosService.FieldSelector.ID, null, true)); assertEquals(5, hits.size()); assertTrue(hits.contains(line1Infos)); assertTrue(hits.contains(line2Infos)); @@ -227,7 +227,7 @@ void searchModifiedEquipment() { equipmentInfosService.addEquipmentInfos(loadInfos); // Searching for the equipment by ID and checking if the list size is 1, indicating successful retrieval. - List list = studyService.searchEquipments(STUDY_UUID, NODE_UUID, "loadId1", EquipmentInfosService.FieldSelector.ID, null, false); + List list = studyService.searchEquipments(NODE_UUID, ROOTNETWORK_UUID, "loadId1", EquipmentInfosService.FieldSelector.ID, null, false); assertEquals(1, list.size()); // Adding another version of the same equipment but with a different variant ID. @@ -235,7 +235,7 @@ void searchModifiedEquipment() { equipmentInfosService.addEquipmentInfos(loadInfos1); // Searching for the equipment by ID to check if the correct version is retrieved. - list = studyService.searchEquipments(STUDY_UUID, VARIANT_NODE_UUID, "loadId1", EquipmentInfosService.FieldSelector.ID, null, false); + list = studyService.searchEquipments(VARIANT_NODE_UUID, ROOTNETWORK_UUID, "loadId1", EquipmentInfosService.FieldSelector.ID, null, false); assertEquals(1, list.size()); assertTrue(list.contains(loadInfos1)); @@ -244,12 +244,12 @@ void searchModifiedEquipment() { equipmentInfosService.addEquipmentInfos(loadInfos2); // Searching for the third version of the equipment and validating its presence in the results. - list = studyService.searchEquipments(STUDY_UUID, VARIANT_NODE_UUID_2, "loadId1", EquipmentInfosService.FieldSelector.ID, null, false); + list = studyService.searchEquipments(VARIANT_NODE_UUID_2, ROOTNETWORK_UUID, "loadId1", EquipmentInfosService.FieldSelector.ID, null, false); assertEquals(1, list.size()); assertTrue(list.contains(loadInfos2)); // Re-searching for the second version of the equipment to ensure it is still retrievable without third version. - list = studyService.searchEquipments(STUDY_UUID, VARIANT_NODE_UUID, "loadId1", EquipmentInfosService.FieldSelector.ID, null, false); + list = studyService.searchEquipments(VARIANT_NODE_UUID, ROOTNETWORK_UUID, "loadId1", EquipmentInfosService.FieldSelector.ID, null, false); assertEquals(1, list.size()); assertTrue(list.contains(loadInfos1)); } @@ -263,7 +263,7 @@ void testSearchForModifiedEquipmentsFilteredByType() { equipmentInfosService.addEquipmentInfos(generatorInfos); // Searching for LOAD equipment by ID and verifying it's correctly retrieved. - List list = studyService.searchEquipments(STUDY_UUID, NODE_UUID, "loadId1", EquipmentInfosService.FieldSelector.ID, "LOAD", false); + List list = studyService.searchEquipments(NODE_UUID, ROOTNETWORK_UUID, "loadId1", EquipmentInfosService.FieldSelector.ID, "LOAD", false); assertEquals(1, list.size()); // Adding new versions of LOAD and GENERATOR equipment with a different variant ID. @@ -273,12 +273,12 @@ void testSearchForModifiedEquipmentsFilteredByType() { equipmentInfosService.addEquipmentInfos(generatorInfos1); // Searching for the new version of LOAD equipment and verifying the correct variant is retrieved. - list = studyService.searchEquipments(STUDY_UUID, VARIANT_NODE_UUID, "loadId1", EquipmentInfosService.FieldSelector.ID, "LOAD", false); + list = studyService.searchEquipments(VARIANT_NODE_UUID, ROOTNETWORK_UUID, "loadId1", EquipmentInfosService.FieldSelector.ID, "LOAD", false); assertEquals(1, list.size()); assertTrue(list.contains(loadInfos1)); // Searching for the new version of GENERATOR equipment and verifying the correct variant is retrieved. - list = studyService.searchEquipments(STUDY_UUID, VARIANT_NODE_UUID, "id_g1", EquipmentInfosService.FieldSelector.ID, "GENERATOR", false); + list = studyService.searchEquipments(VARIANT_NODE_UUID, ROOTNETWORK_UUID, "id_g1", EquipmentInfosService.FieldSelector.ID, "GENERATOR", false); assertEquals(1, list.size()); assertTrue(list.contains(generatorInfos1)); @@ -289,18 +289,18 @@ void testSearchForModifiedEquipmentsFilteredByType() { equipmentInfosService.addEquipmentInfos(generatorInfos2); // Searching for the second set of equipment and verifying both LOAD and GENERATOR types are correctly retrieved. - list = studyService.searchEquipments(STUDY_UUID, VARIANT_NODE_UUID_2, "loadId1", EquipmentInfosService.FieldSelector.ID, "LOAD", false); + list = studyService.searchEquipments(VARIANT_NODE_UUID_2, ROOTNETWORK_UUID, "loadId1", EquipmentInfosService.FieldSelector.ID, "LOAD", false); assertEquals(1, list.size()); assertTrue(list.contains(loadInfos2)); - list = studyService.searchEquipments(STUDY_UUID, VARIANT_NODE_UUID_2, "id_g1", EquipmentInfosService.FieldSelector.ID, "GENERATOR", false); + list = studyService.searchEquipments(VARIANT_NODE_UUID_2, ROOTNETWORK_UUID, "id_g1", EquipmentInfosService.FieldSelector.ID, "GENERATOR", false); assertEquals(1, list.size()); assertTrue(list.contains(generatorInfos2)); // Re-verifying the retrieval of the first set of modified equipment for both LOAD and GENERATOR types without redandante. - list = studyService.searchEquipments(STUDY_UUID, VARIANT_NODE_UUID, "loadId1", EquipmentInfosService.FieldSelector.ID, "LOAD", false); + list = studyService.searchEquipments(VARIANT_NODE_UUID, ROOTNETWORK_UUID, "loadId1", EquipmentInfosService.FieldSelector.ID, "LOAD", false); assertEquals(1, list.size()); assertTrue(list.contains(loadInfos1)); - list = studyService.searchEquipments(STUDY_UUID, VARIANT_NODE_UUID, "id_g1", EquipmentInfosService.FieldSelector.ID, "GENERATOR", false); + list = studyService.searchEquipments(VARIANT_NODE_UUID, ROOTNETWORK_UUID, "id_g1", EquipmentInfosService.FieldSelector.ID, "GENERATOR", false); assertEquals(1, list.size()); assertTrue(list.contains(generatorInfos1)); } diff --git a/src/test/java/org/gridsuite/study/server/StudyServiceTest.java b/src/test/java/org/gridsuite/study/server/StudyServiceTest.java index 18d9865d2..39cb4f943 100644 --- a/src/test/java/org/gridsuite/study/server/StudyServiceTest.java +++ b/src/test/java/org/gridsuite/study/server/StudyServiceTest.java @@ -164,7 +164,7 @@ void testRecreateStudyNetworkWithStudyCaseAndImportParameters() throws Exception UUID caseExistsStubId = wireMockUtils.stubCaseExists(CASE_UUID.toString(), true); CountDownLatch countDownLatch = new CountDownLatch(1); - UUID postNetworkStubId = wireMockUtils.stubImportNetwork(CASE_UUID.toString(), importParameters, NETWORK_UUID.toString(), "20140116_0830_2D4_UX1_pst", "UCTE", countDownLatch); + UUID postNetworkStubId = wireMockUtils.stubImportNetwork(CASE_UUID.toString(), importParameters, NETWORK_UUID.toString(), "20140116_0830_2D4_UX1_pst", "UCTE", "20140116_0830_2D4_UX1_pst.ucte", countDownLatch); UUID disableCaseExpirationStubId = wireMockUtils.stubDisableCaseExpiration(CASE_UUID.toString()); mockMvc.perform(post("/v1/studies/{studyUuid}/network", studyUuid) @@ -209,7 +209,7 @@ void testRecreateStudyNetworkFromExistingCase() throws Exception { UUID caseExistsStubId = wireMockUtils.stubCaseExists(CASE_UUID.toString(), true); CountDownLatch countDownLatch = new CountDownLatch(1); - UUID postNetworkStubId = wireMockUtils.stubImportNetwork(CASE_UUID_STRING, newImportParameters, NETWORK_UUID.toString(), "20140116_0830_2D4_UX1_pst", "UCTE", countDownLatch); + UUID postNetworkStubId = wireMockUtils.stubImportNetwork(CASE_UUID_STRING, newImportParameters, NETWORK_UUID.toString(), "20140116_0830_2D4_UX1_pst", "UCTE", "20140116_0830_2D4_UX1_pst.ucte", countDownLatch); UUID disableCaseExpirationStubId = wireMockUtils.stubDisableCaseExpiration(CASE_UUID.toString()); mockMvc.perform(post("/v1/studies/{studyUuid}/network", studyUuid) @@ -257,7 +257,7 @@ private UUID createStudy(String userId, UUID caseUuid, Map impor // mock API calls UUID caseExistsStubId = wireMockUtils.stubCaseExists(caseUuid.toString(), true); CountDownLatch countDownLatch = new CountDownLatch(1); - UUID postNetworkStubId = wireMockUtils.stubImportNetwork(caseUuid.toString(), importParameters, NETWORK_UUID.toString(), "20140116_0830_2D4_UX1_pst", "UCTE", countDownLatch); + UUID postNetworkStubId = wireMockUtils.stubImportNetwork(caseUuid.toString(), importParameters, NETWORK_UUID.toString(), "20140116_0830_2D4_UX1_pst", "UCTE", "20140116_0830_2D4_UX1_pst.ucte", countDownLatch); UUID disableCaseExpirationStubId = wireMockUtils.stubDisableCaseExpiration(caseUuid.toString()); when(loadFlowService.createDefaultLoadFlowParameters()).thenReturn(LOADFLOW_PARAMETERS_UUID); when(shortCircuitService.createParameters(null)).thenReturn(SHORTCIRCUIT_PARAMETERS_UUID); diff --git a/src/test/java/org/gridsuite/study/server/StudyTest.java b/src/test/java/org/gridsuite/study/server/StudyTest.java index 1e0430def..410d65316 100644 --- a/src/test/java/org/gridsuite/study/server/StudyTest.java +++ b/src/test/java/org/gridsuite/study/server/StudyTest.java @@ -44,6 +44,8 @@ import org.gridsuite.study.server.repository.StudyCreationRequestRepository; import org.gridsuite.study.server.repository.StudyEntity; import org.gridsuite.study.server.repository.StudyRepository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkEntity; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkRepository; import org.gridsuite.study.server.service.*; import org.gridsuite.study.server.service.shortcircuit.ShortCircuitService; import org.gridsuite.study.server.utils.*; @@ -90,6 +92,7 @@ import static org.gridsuite.study.server.StudyConstants.CASE_API_VERSION; import static org.gridsuite.study.server.StudyConstants.HEADER_USER_ID; import static org.gridsuite.study.server.StudyException.Type.STUDY_NOT_FOUND; +import static org.gridsuite.study.server.StudyException.Type.ROOTNETWORK_NOT_FOUND; import static org.gridsuite.study.server.notification.NotificationService.DEFAULT_ERROR_MESSAGE; import static org.gridsuite.study.server.notification.NotificationService.UPDATE_TYPE_COMPUTATION_PARAMETERS; import static org.gridsuite.study.server.utils.MatcherBasicStudyInfos.createMatcherStudyBasicInfos; @@ -231,6 +234,9 @@ class StudyTest { @MockBean private StudyInfosService studyInfosService; + @Autowired + private StudyService studyService; + @Autowired private ObjectMapper mapper; @@ -265,6 +271,10 @@ class StudyTest { private final String elementUpdateDestination = "element.update"; private boolean indexed = false; + @Autowired + private RootNetworkRepository rootNetworkRepository; + @Autowired + private RootNetworkService rootNetworkService; private static EquipmentInfos toEquipmentInfos(Line line) { return EquipmentInfos.builder() @@ -596,6 +606,7 @@ private void sendCaseImportSucceededMessage(String requestPath, NetworkInfos net .setHeader("networkUuid", networkInfos.getNetworkUuid().toString()) .setHeader("networkId", networkInfos.getNetworkId()) .setHeader("caseFormat", format) + .setHeader("caseName", "caseName") .setHeader("importParameters", importParameters) .build(), "case.import.succeeded"); } @@ -848,8 +859,9 @@ void testDeleteStudyWithNonExistingCase(final MockWebServer server) throws Excep StudyEntity studyEntity = studyRepository.findById(studyUuid).orElse(null); assertNotNull(studyEntity); UUID nonExistingCaseUuid = UUID.randomUUID(); - studyEntity.setCaseUuid(nonExistingCaseUuid); - studyRepository.save(studyEntity); + RootNetworkEntity rootNetworkEntity = rootNetworkRepository.findAllByStudyId(studyUuid).stream().findFirst().orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND)); + rootNetworkEntity.setCaseUuid(nonExistingCaseUuid); + rootNetworkRepository.save(rootNetworkEntity); mockMvc.perform(delete("/v1/studies/{studyUuid}", studyUuid).header(USER_ID_HEADER, "userId")) .andExpect(status().isOk()); @@ -944,16 +956,17 @@ void testGetNodeReportLogs(final MockWebServer server) throws Exception { void testGetParentNodesReportLogs(final MockWebServer server) throws Exception { String userId = "userId"; UUID studyUuid = createStudy(server, userId, CASE_UUID); + UUID rootNetworkUuid = rootNetworkRepository.findAllByStudyId(studyUuid).stream().findFirst().orElseThrow(() -> new StudyException(StudyException.Type.ROOTNETWORK_NOT_FOUND)).getId(); RootNode rootNode = networkModificationTreeService.getStudyTree(studyUuid); UUID modificationNodeUuid = rootNode.getChildren().get(0).getId(); AbstractNode modificationNode = rootNode.getChildren().get(0); NetworkModificationNode node1 = createNetworkModificationNode(studyUuid, modificationNodeUuid, VARIANT_ID, "node1", userId); NetworkModificationNode node2 = createNetworkModificationNode(studyUuid, node1.getId(), VARIANT_ID_2, "node2", userId); createNetworkModificationNode(studyUuid, modificationNodeUuid, VARIANT_ID_3, "node3", userId); - UUID rootNodeReportId = networkModificationTreeService.getReportUuid(rootNode.getId()); - UUID modificationNodeReportId = networkModificationTreeService.getReportUuid(modificationNode.getId()); - UUID node1ReportId = networkModificationTreeService.getReportUuid(node1.getId()); - UUID node2ReportId = networkModificationTreeService.getReportUuid(node2.getId()); + UUID rootNodeReportId = networkModificationTreeService.getReportUuid(rootNode.getId(), rootNetworkUuid); + UUID modificationNodeReportId = networkModificationTreeService.getReportUuid(modificationNode.getId(), rootNetworkUuid); + UUID node1ReportId = networkModificationTreeService.getReportUuid(node1.getId(), rootNetworkUuid); + UUID node2ReportId = networkModificationTreeService.getReportUuid(node2.getId(), rootNetworkUuid); // root // | @@ -1595,7 +1608,9 @@ private StudyEntity duplicateStudy(final MockWebServer server, UUID studyUuid) t numberOfRequests++; } requests = TestUtils.getRequestsWithBodyDone(numberOfRequests, server); - assertEquals(1, requests.stream().filter(r -> r.getPath().matches("/v1/networks/" + duplicatedStudy.getNetworkUuid() + "/reindex-all")).count()); + + RootNetworkEntity rootNetworkEntity = rootNetworkRepository.findAllByStudyId(duplicatedStudy.getId()).stream().findFirst().orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND)); + assertEquals(1, requests.stream().filter(r -> r.getPath().matches("/v1/networks/" + rootNetworkEntity.getNetworkUuid() + "/reindex-all")).count()); assertEquals(1, requests.stream().filter(r -> r.getPath().matches("/v1/cases\\?duplicateFrom=.*&withExpiration=false")).count()); if (sourceStudy.getVoltageInitParametersUuid() != null) { assertEquals(1, requests.stream().filter(r -> r.getPath().matches("/v1/parameters\\?duplicateFrom=" + sourceStudy.getVoltageInitParametersUuid())).count()); @@ -1808,6 +1823,7 @@ void testCutAndPasteNodeAroundItself(final MockWebServer mockWebServer) throws E void testCutAndPasteNodeWithoutModification(final MockWebServer server) throws Exception { String userId = "userId"; UUID study1Uuid = createStudy(server, userId, CASE_UUID); + UUID rootNetworkUuid = rootNetworkRepository.findAllByStudyId(study1Uuid).stream().findFirst().orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND)).getId(); RootNode rootNode = networkModificationTreeService.getStudyTree(study1Uuid); UUID modificationNodeUuid = rootNode.getChildren().get(0).getId(); NetworkModificationNode node1 = createNetworkModificationNode(study1Uuid, modificationNodeUuid, UUID.randomUUID(), VARIANT_ID, "node1", BuildStatus.BUILT, userId); @@ -1820,15 +1836,16 @@ void testCutAndPasteNodeWithoutModification(final MockWebServer server) throws E Set request = TestUtils.getRequestsDone(1, server); assertTrue(request.stream().allMatch(r -> r.matches("/v1/reports"))); - assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(emptyNode.getId()).getGlobalBuildStatus()); - assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(node1.getId()).getGlobalBuildStatus()); - assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(emptyNodeChild.getId()).getGlobalBuildStatus()); + assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(emptyNode.getId(), rootNetworkUuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(node1.getId(), rootNetworkUuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(emptyNodeChild.getId(), rootNetworkUuid).getGlobalBuildStatus()); } @Test void testCutAndPasteNodeWithModification(final MockWebServer server) throws Exception { String userId = "userId"; UUID study1Uuid = createStudy(server, userId, CASE_UUID); + UUID rootNetworkUuid = rootNetworkRepository.findAllByStudyId(study1Uuid).stream().findFirst().orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND)).getId(); RootNode rootNode = networkModificationTreeService.getStudyTree(study1Uuid); UUID modificationNodeUuid = rootNode.getChildren().get(0).getId(); NetworkModificationNode node1 = createNetworkModificationNode(study1Uuid, modificationNodeUuid, UUID.randomUUID(), VARIANT_ID, "node1", BuildStatus.BUILT, userId); @@ -1841,9 +1858,9 @@ void testCutAndPasteNodeWithModification(final MockWebServer server) throws Exce Set request = TestUtils.getRequestsDone(2, server); assertTrue(request.stream().allMatch(r -> r.matches("/v1/reports"))); - assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(notEmptyNode.getId()).getGlobalBuildStatus()); - assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(node1.getId()).getGlobalBuildStatus()); - assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(notEmptyNodeChild.getId()).getGlobalBuildStatus()); + assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(notEmptyNode.getId(), rootNetworkUuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(node1.getId(), rootNetworkUuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(notEmptyNodeChild.getId(), rootNetworkUuid).getGlobalBuildStatus()); } @Test @@ -1883,6 +1900,7 @@ void testCutAndPastErrors(final MockWebServer mockWebServer) throws Exception { void testCutAndPasteSubtree(final MockWebServer server) throws Exception { String userId = "userId"; UUID study1Uuid = createStudy(server, userId, CASE_UUID); + UUID rootNetworkUuid = rootNetworkRepository.findAllByStudyId(study1Uuid).stream().findFirst().orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND)).getId(); RootNode rootNode = networkModificationTreeService.getStudyTree(study1Uuid); UUID modificationNodeUuid = rootNode.getChildren().get(0).getId(); NetworkModificationNode node1 = createNetworkModificationNode(study1Uuid, modificationNodeUuid, UUID.randomUUID(), VARIANT_ID, "node1", BuildStatus.BUILT, userId); @@ -1929,9 +1947,9 @@ void testCutAndPasteSubtree(final MockWebServer server) throws Exception { var request = TestUtils.getRequestsDone(1, server); assertTrue(request.stream().allMatch(r -> r.matches("/v1/reports"))); - assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(node1.getId()).getGlobalBuildStatus()); - assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(emptyNode.getId()).getGlobalBuildStatus()); - assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(emptyNodeChild.getId()).getGlobalBuildStatus()); + assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(node1.getId(), rootNetworkUuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(emptyNode.getId(), rootNetworkUuid).getGlobalBuildStatus()); + assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(emptyNodeChild.getId(), rootNetworkUuid).getGlobalBuildStatus()); mockMvc.perform(get(STUDIES_URL + "/{studyUuid}/subtree?parentNodeUuid={parentSubtreeNode}", @@ -2051,15 +2069,17 @@ void testDuplicateNode(final MockWebServer mockWebServer) throws Exception { .andExpect(status().isForbidden()); // Test Built status when duplicating an empty node - assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(node3.getId()).getGlobalBuildStatus()); + UUID rootNetworkUuid = studyService.getStudyFirstRootNetworkUuid(study1Uuid); + assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(node3.getId(), rootNetworkUuid).getGlobalBuildStatus()); duplicateNode(study1Uuid, study1Uuid, emptyNode, node3.getId(), InsertMode.BEFORE, userId); - assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(node3.getId()).getGlobalBuildStatus()); + assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(node3.getId(), rootNetworkUuid).getGlobalBuildStatus()); } @Test void testDuplicateSubtree(final MockWebServer server) throws Exception { String userId = "userId"; UUID study1Uuid = createStudy(server, userId, CASE_UUID); + UUID rootNetworkUuid = rootNetworkRepository.findAllByStudyId(study1Uuid).stream().findFirst().orElseThrow(() -> new StudyException(ROOTNETWORK_NOT_FOUND)).getId(); RootNode rootNode = networkModificationTreeService.getStudyTree(study1Uuid); UUID modificationNodeUuid = rootNode.getChildren().get(0).getId(); NetworkModificationNode node1 = createNetworkModificationNode(study1Uuid, modificationNodeUuid, VARIANT_ID, "node1", userId); @@ -2092,7 +2112,7 @@ void testDuplicateSubtree(final MockWebServer server) throws Exception { wireMockUtils.verifyNetworkModificationPostWithVariant(stubUuid, createTwoWindingsTransformerAttributes, NETWORK_UUID_STRING, VARIANT_ID); // Invalidation node 3 - assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(node3.getId()).getGlobalBuildStatus()); + assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(node3.getId(), rootNetworkUuid).getGlobalBuildStatus()); Set requests = TestUtils.getRequestsWithBodyDone(1, server); assertEquals(1, requests.stream().filter(r -> r.getPath().matches("/v1/reports")).count()); @@ -2180,9 +2200,9 @@ void testDuplicateSubtree(final MockWebServer server) throws Exception { .count()); //node2 should be built - assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(node2.getId()).getGlobalBuildStatus()); + assertEquals(BuildStatus.BUILT, networkModificationTreeService.getNodeBuildStatus(node2.getId(), rootNetworkUuid).getGlobalBuildStatus()); //duplicated node2 should now be not built - assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(nodesAfterDuplication.get(1)).getGlobalBuildStatus()); + assertEquals(BuildStatus.NOT_BUILT, networkModificationTreeService.getNodeBuildStatus(nodesAfterDuplication.get(1), rootNetworkUuid).getGlobalBuildStatus()); //try copy non-existing node and expect not found mockMvc.perform(post(STUDIES_URL + diff --git a/src/test/java/org/gridsuite/study/server/SupervisionControllerTest.java b/src/test/java/org/gridsuite/study/server/SupervisionControllerTest.java index b82f3adc9..f78a335b7 100644 --- a/src/test/java/org/gridsuite/study/server/SupervisionControllerTest.java +++ b/src/test/java/org/gridsuite/study/server/SupervisionControllerTest.java @@ -100,11 +100,11 @@ private static EquipmentInfos toEquipmentInfos(Identifiable i) { } private StudyEntity insertDummyStudy(UUID networkUuid, UUID caseUuid, String caseName) { - StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, caseUuid, caseName, ""); + StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, caseUuid, caseName, "", UUID.randomUUID()); studyEntity.setId(STUDY_UUID); studyEntity.setIndexationStatus(StudyIndexationStatus.INDEXED); var study = studyRepository.save(studyEntity); - networkModificationTreeService.createRoot(studyEntity, null); + networkModificationTreeService.createRoot(studyEntity); return study; } @@ -115,7 +115,8 @@ void setup() { network.getIdentifiables().forEach(idable -> equipmentInfosService.addEquipmentInfos(toEquipmentInfos(idable))); when(networkStoreService.getNetworkUuid(STUDY_UUID)).thenReturn(NETWORK_UUID); - when(networkModificationTreeService.getVariantId(NODE_UUID)).thenReturn(VariantManagerConstants.INITIAL_VARIANT_ID); + //TODO: removing it still works, check if it's normal +// when(networkModificationTreeService.getVariantId(NODE_UUID, any())).thenReturn(VariantManagerConstants.INITIAL_VARIANT_ID); when(networkModificationTreeService.getStudyTree(STUDY_UUID)).thenReturn(RootNode.builder().studyId(STUDY_UUID).id(NODE_UUID).build()); when(networkConversionService.checkStudyIndexationStatus(NETWORK_UUID)).thenReturn(true); } diff --git a/src/test/java/org/gridsuite/study/server/VoltageInitTest.java b/src/test/java/org/gridsuite/study/server/VoltageInitTest.java index c23aee016..829f16727 100644 --- a/src/test/java/org/gridsuite/study/server/VoltageInitTest.java +++ b/src/test/java/org/gridsuite/study/server/VoltageInitTest.java @@ -35,7 +35,7 @@ import org.gridsuite.study.server.notification.dto.StudyAlert; import org.gridsuite.study.server.repository.StudyEntity; import org.gridsuite.study.server.repository.StudyRepository; -import org.gridsuite.study.server.repository.networkmodificationtree.NetworkModificationNodeInfoRepository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkNodeInfoRepository; import org.gridsuite.study.server.repository.nonevacuatedenergy.NonEvacuatedEnergyParametersEntity; import org.gridsuite.study.server.service.*; import org.gridsuite.study.server.service.shortcircuit.ShortCircuitService; @@ -196,7 +196,7 @@ class VoltageInitTest { private NetworkStoreService networkStoreService; @Autowired - private NetworkModificationNodeInfoRepository networkModificationNodeInfoRepository; + private RootNetworkNodeInfoRepository rootNetworkNodeInfoRepository; //output destinations private final String studyUpdateDestination = "study.update"; @@ -240,7 +240,7 @@ public MockResponse dispatch(RecordedRequest request) { if (path.matches("/v1/networks/" + NETWORK_UUID_STRING + "/run-and-save\\?receiver=.*&reportUuid=.*&reporterId=.*&variantId=" + VARIANT_ID_3)) { input.send(MessageBuilder.withPayload("") .setHeader("resultUuid", VOLTAGE_INIT_CANCEL_FAILED_UUID) - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .setHeader(HEADER_REACTIVE_SLACKS_OVER_THRESHOLD, Boolean.TRUE) .setHeader(HEADER_REACTIVE_SLACKS_THRESHOLD_VALUE, 10.) .build(), voltageInitResultDestination); @@ -248,14 +248,14 @@ public MockResponse dispatch(RecordedRequest request) { } else if (path.matches("/v1/networks/" + NETWORK_UUID_STRING + "/run-and-save\\?receiver=.*&reportUuid=.*&reporterId=.*&variantId=" + VARIANT_ID_2)) { input.send(MessageBuilder.withPayload("") .setHeader("resultUuid", VOLTAGE_INIT_RESULT_UUID) - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .setHeader(HEADER_REACTIVE_SLACKS_OVER_THRESHOLD, Boolean.TRUE) .setHeader(HEADER_REACTIVE_SLACKS_THRESHOLD_VALUE, 10.) .build(), voltageInitResultDestination); return new MockResponse(200, Headers.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE), voltageInitResultUuidStr); } else if (path.matches("/v1/networks/" + NETWORK_UUID_STRING + "/run-and-save\\?receiver=.*&reportUuid=.*&reporterId=.*&variantId=" + VARIANT_ID)) { input.send(MessageBuilder.withPayload("") - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .setHeader("resultUuid", VOLTAGE_INIT_ERROR_RESULT_UUID) .build(), voltageInitFailedDestination); return new MockResponse(200, Headers.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE), voltageInitErrorResultUuidStr); @@ -277,7 +277,7 @@ public MockResponse dispatch(RecordedRequest request) { String resultUuid = path.matches(".*variantId=" + VARIANT_ID_2 + ".*") ? VOLTAGE_INIT_OTHER_NODE_RESULT_UUID : VOLTAGE_INIT_RESULT_UUID; input.send(MessageBuilder.withPayload("") .setHeader("resultUuid", resultUuid) - .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%22userId%22%3A%22userId%22%7D") + .setHeader("receiver", "%7B%22nodeUuid%22%3A%22" + request.getPath().split("%")[5].substring(4) + "%22%2C%20%22rootNetworkUuid%22%3A%20%22" + request.getPath().split("%")[11].substring(4) + "%22%2C%20%22userId%22%3A%22userId%22%7D") .build(), voltageInitStoppedDestination); return new MockResponse(200); } else if (path.matches("/v1/results/" + VOLTAGE_INIT_CANCEL_FAILED_UUID + "/stop.*")) { @@ -671,14 +671,15 @@ private void checkEquipmentUpdatingMessagesReceived(UUID studyNameUserIdUuid, UU void testNotResetedUuidResultWhenVoltageInitFailed() throws Exception { UUID resultUuid = UUID.randomUUID(); StudyEntity studyEntity = insertDummyStudy(UUID.randomUUID(), UUID.randomUUID(), UUID.fromString(VOLTAGE_INIT_PARAMETERS_UUID), false); + UUID rootNetworkUuid = studyEntity.getFirstRootNetwork().getId(); RootNode rootNode = networkModificationTreeService.getStudyTree(studyEntity.getId()); NetworkModificationNode modificationNode = createNetworkModificationNode(studyEntity.getId(), rootNode.getId(), UUID.randomUUID(), VARIANT_ID, "node 1"); - String resultUuidJson = objectMapper.writeValueAsString(new NodeReceiver(modificationNode.getId())); + String resultUuidJson = objectMapper.writeValueAsString(new NodeReceiver(modificationNode.getId(), rootNetworkUuid)); // Set an uuid result in the database - networkModificationTreeService.updateComputationResultUuid(modificationNode.getId(), resultUuid, VOLTAGE_INITIALIZATION); - assertTrue(networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), VOLTAGE_INITIALIZATION).isPresent()); - assertEquals(resultUuid, networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), VOLTAGE_INITIALIZATION).get()); + networkModificationTreeService.updateComputationResultUuid(modificationNode.getId(), rootNetworkUuid, resultUuid, VOLTAGE_INITIALIZATION); + assertTrue(networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), rootNetworkUuid, VOLTAGE_INITIALIZATION) != null); + assertEquals(resultUuid, networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), rootNetworkUuid, VOLTAGE_INITIALIZATION)); StudyService studyService = Mockito.mock(StudyService.class); doAnswer(invocation -> { @@ -688,11 +689,11 @@ void testNotResetedUuidResultWhenVoltageInitFailed() throws Exception { .setHeader("resultUuid", VOLTAGE_INIT_ERROR_RESULT_UUID) .build(), voltageInitFailedDestination); return resultUuid; - }).when(studyService).runVoltageInit(any(), any(), any()); - studyService.runVoltageInit(studyEntity.getId(), modificationNode.getId(), ""); + }).when(studyService).runVoltageInit(any(), any(), any(), any()); + studyService.runVoltageInit(studyEntity.getId(), modificationNode.getId(), rootNetworkUuid, ""); // Test doesn't reset uuid result in the database - assertEquals(VOLTAGE_INIT_ERROR_RESULT_UUID, networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), VOLTAGE_INITIALIZATION).get().toString()); + assertEquals(VOLTAGE_INIT_ERROR_RESULT_UUID, networkModificationTreeService.getComputationResultUuid(modificationNode.getId(), rootNetworkUuid, VOLTAGE_INITIALIZATION).toString()); Message message = output.receive(TIMEOUT, studyUpdateDestination); assertEquals(studyEntity.getId(), message.getHeaders().get(NotificationService.HEADER_STUDY_UUID)); @@ -733,7 +734,7 @@ private void testResultCount(final MockWebServer server) throws Exception { } private void testDeleteResults(final MockWebServer server, int expectedInitialResultCount) throws Exception { - assertEquals(expectedInitialResultCount, networkModificationNodeInfoRepository.findAllByVoltageInitResultUuidNotNull().size()); + assertEquals(expectedInitialResultCount, rootNetworkNodeInfoRepository.findAllByVoltageInitResultUuidNotNull().size()); mockMvc.perform(delete("/v1/supervision/computation/results") .queryParam("type", VOLTAGE_INITIALIZATION.toString()) .queryParam("dryRun", "false")) @@ -742,7 +743,7 @@ private void testDeleteResults(final MockWebServer server, int expectedInitialRe var requests = TestUtils.getRequestsDone(2, server); assertTrue(requests.contains("/v1/results")); assertTrue(requests.stream().anyMatch(r -> r.matches("/v1/reports"))); - assertEquals(0, networkModificationNodeInfoRepository.findAllByVoltageInitResultUuidNotNull().size()); + assertEquals(0, rootNetworkNodeInfoRepository.findAllByVoltageInitResultUuidNotNull().size()); } @Test @@ -770,11 +771,11 @@ void testNoResult() throws Exception { private StudyEntity insertDummyStudy(UUID networkUuid, UUID caseUuid, UUID voltageInitParametersUuid, boolean applyModifications) { NonEvacuatedEnergyParametersEntity defaultNonEvacuatedEnergyParametersEntity = NonEvacuatedEnergyService.toEntity(NonEvacuatedEnergyService.getDefaultNonEvacuatedEnergyParametersInfos()); - StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, caseUuid, "", + StudyEntity studyEntity = TestUtils.createDummyStudy(networkUuid, "netId", caseUuid, "", "", null, UUID.randomUUID(), null, voltageInitParametersUuid, null, null, defaultNonEvacuatedEnergyParametersEntity, applyModifications); var study = studyRepository.save(studyEntity); - networkModificationTreeService.createRoot(studyEntity, null); + networkModificationTreeService.createRoot(studyEntity); return study; } diff --git a/src/test/java/org/gridsuite/study/server/repository/RepositoriesTest.java b/src/test/java/org/gridsuite/study/server/repository/RepositoriesTest.java index 997f52fba..ec5f843d9 100644 --- a/src/test/java/org/gridsuite/study/server/repository/RepositoriesTest.java +++ b/src/test/java/org/gridsuite/study/server/repository/RepositoriesTest.java @@ -6,6 +6,7 @@ */ package org.gridsuite.study.server.repository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkEntity; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -13,6 +14,7 @@ import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.transaction.annotation.Transactional; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -44,32 +46,45 @@ void testStudyRepository() { UUID shortCircuitParametersUuid2 = UUID.randomUUID(); UUID shortCircuitParametersUuid3 = UUID.randomUUID(); - StudyEntity studyEntity1 = studyRepository.save(StudyEntity.builder() + StudyEntity studyEntity = StudyEntity.builder() .id(UUID.randomUUID()) - .networkUuid(UUID.randomUUID()) - .networkId("networkId") - .caseFormat("caseFormat") - .caseUuid(UUID.randomUUID()) .shortCircuitParametersUuid(shortCircuitParametersUuid1) - .build()); + .build(); + RootNetworkEntity rootNetworkEntity1 = RootNetworkEntity.builder() + .networkUuid(UUID.randomUUID()) + .networkId("networkId") + .caseFormat("caseFormat") + .caseName("caseName1") + .caseUuid(UUID.randomUUID()).build(); + studyEntity.addRootNetwork(rootNetworkEntity1); + StudyEntity studyEntity1 = studyRepository.save(studyEntity); StudyEntity studyEntity2 = studyRepository.save(StudyEntity.builder() .id(UUID.randomUUID()) - .networkUuid(UUID.randomUUID()) - .networkId("networkId2") - .caseFormat("caseFormat2") - .caseUuid(UUID.randomUUID()) + .rootNetworks(List.of(RootNetworkEntity.builder() + .networkUuid(UUID.randomUUID()) + .networkId("networkId2") + .caseFormat("caseFormat2") + .caseName("caseName2") + .caseUuid(UUID.randomUUID()) + .build() + )) .shortCircuitParametersUuid(shortCircuitParametersUuid2) .build()); - studyRepository.save(StudyEntity.builder() - .id(UUID.randomUUID()) - .networkUuid(UUID.randomUUID()) - .networkId("networkId3") - .caseFormat("caseFormat3") - .caseUuid(UUID.randomUUID()) - .shortCircuitParametersUuid(shortCircuitParametersUuid3) - .build()); + StudyEntity studyEntity3 = StudyEntity.builder() + .id(UUID.randomUUID()) + .shortCircuitParametersUuid(shortCircuitParametersUuid3) + .build(); + RootNetworkEntity rootNetworkEntity3 = RootNetworkEntity.builder() + .networkUuid(UUID.randomUUID()) + .networkId("networkId3") + .caseFormat("caseFormat3") + .caseName("caseName3") + .caseUuid(UUID.randomUUID()) + .build(); + studyEntity3.addRootNetwork(rootNetworkEntity3); + studyRepository.save(studyEntity3); assertThat(studyEntity1).as("studyEntity1").extracting(StudyEntity::getId).isNotNull(); assertThat(studyEntity2).as("studyEntity2").extracting(StudyEntity::getId).isNotNull(); @@ -100,10 +115,12 @@ void testStudyImportParameters() { Map importParametersExpected = Map.of("param1", "changedValue1, changedValue2", "param2", "changedValue"); StudyEntity studyEntityToSave = StudyEntity.builder() .id(UUID.randomUUID()) - .networkUuid(UUID.randomUUID()) - .networkId("networkId") - .caseFormat("caseFormat") - .caseUuid(UUID.randomUUID()) + .rootNetworks(List.of(RootNetworkEntity.builder() + .networkUuid(UUID.randomUUID()) + .networkId("networkId") + .caseFormat("caseFormat") + .caseName("caseName") + .caseUuid(UUID.randomUUID()).build())) .importParameters(importParametersExpected) .build(); diff --git a/src/test/java/org/gridsuite/study/server/service/ReportServiceTest.java b/src/test/java/org/gridsuite/study/server/service/ReportServiceTest.java index 64f998f50..9b6e84853 100644 --- a/src/test/java/org/gridsuite/study/server/service/ReportServiceTest.java +++ b/src/test/java/org/gridsuite/study/server/service/ReportServiceTest.java @@ -19,12 +19,14 @@ import okhttp3.Headers; import okhttp3.HttpUrl; import org.gridsuite.study.server.ContextConfigurationWithTestChannel; +import org.gridsuite.study.server.StudyException; import org.gridsuite.study.server.dto.Report; import org.gridsuite.study.server.networkmodificationtree.dto.InsertMode; import org.gridsuite.study.server.networkmodificationtree.dto.NetworkModificationNode; import org.gridsuite.study.server.networkmodificationtree.dto.RootNode; import org.gridsuite.study.server.repository.StudyEntity; import org.gridsuite.study.server.repository.StudyRepository; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkRepository; import org.gridsuite.study.server.utils.TestUtils; import org.gridsuite.study.server.utils.elasticsearch.DisableElasticsearch; import org.jetbrains.annotations.NotNull; @@ -96,6 +98,10 @@ class ReportServiceTest { private static final String STUDY_UPDATE_DESTINATION = "study.update"; private static final long TIMEOUT = 1000; + @Autowired + private RootNetworkRepository rootNetworkRepository; + @Autowired + private RootNetworkService rootNetworkService; @BeforeEach void setup(final MockWebServer server) { @@ -139,15 +145,16 @@ void tearDown(final MockWebServer server) { } private RootNode createRoot() { - StudyEntity studyEntity = TestUtils.createDummyStudy(UUID.randomUUID(), UUID.randomUUID(), "caseName", ""); + StudyEntity studyEntity = TestUtils.createDummyStudy(UUID.randomUUID(), UUID.randomUUID(), "caseName", "", ROOT_NODE_REPORT_UUID); studyRepository.save(studyEntity); - networkModificationTreeService.createRoot(studyEntity, ROOT_NODE_REPORT_UUID); + networkModificationTreeService.createRoot(studyEntity); return networkModificationTreeService.getStudyTree(studyEntity.getId()); } @Test void testReport(final MockWebServer server) throws Exception { RootNode rootNode = createRoot(); + StudyEntity studyEntity = studyRepository.findById(rootNode.getStudyId()).orElseThrow(() -> new StudyException(StudyException.Type.STUDY_NOT_FOUND)); List expectedRootReports = List.of(getNodeReport(ROOT_NODE_REPORT_UUID, rootNode.getId().toString())); MvcResult mvcResult = mockMvc.perform(get("/v1/studies/{studyUuid}/nodes/{nodeUuid}/parent-nodes-report?nodeOnlyReport=true&reportType=NETWORK_MODIFICATION", rootNode.getStudyId(), rootNode.getId())) @@ -158,7 +165,7 @@ void testReport(final MockWebServer server) throws Exception { checkReports(reports, expectedRootReports); assertTrue(TestUtils.getRequestsDone(1, server).stream().anyMatch(r -> r.matches("/v1/reports/.*"))); - NetworkModificationNode node = (NetworkModificationNode) networkModificationTreeService.createNode(rootNode.getStudyId(), rootNode.getId(), createModificationNodeInfo("Node1"), InsertMode.AFTER, null); + NetworkModificationNode node = networkModificationTreeService.createNode(studyEntity, rootNode.getId(), createModificationNodeInfo("Node1"), InsertMode.AFTER, null); output.receive(TIMEOUT, STUDY_UPDATE_DESTINATION); // message for modification node creation List expectedNodeReports = List.of(getNodeReport(MODIFICATION_NODE_REPORT_UUID, node.getId().toString())); @@ -181,9 +188,10 @@ void testReport(final MockWebServer server) throws Exception { @Test void testMultipleReport(final MockWebServer server) throws Exception { RootNode rootNode = createRoot(); - NetworkModificationNode node = (NetworkModificationNode) networkModificationTreeService.createNode(rootNode.getStudyId(), rootNode.getId(), createModificationNodeInfo("Modification Node"), InsertMode.AFTER, null); - NetworkModificationNode child1 = (NetworkModificationNode) networkModificationTreeService.createNode(rootNode.getStudyId(), node.getId(), createModificationNodeInfo("Child 1"), InsertMode.AFTER, null); - NetworkModificationNode child2 = (NetworkModificationNode) networkModificationTreeService.createNode(rootNode.getStudyId(), node.getId(), createModificationNodeInfo("Child 2"), InsertMode.AFTER, null); + StudyEntity studyEntity = studyRepository.findById(rootNode.getStudyId()).orElseThrow(() -> new StudyException(StudyException.Type.STUDY_NOT_FOUND)); + NetworkModificationNode node = networkModificationTreeService.createNode(studyEntity, rootNode.getId(), createModificationNodeInfo("Modification Node"), InsertMode.AFTER, null); + NetworkModificationNode child1 = networkModificationTreeService.createNode(studyEntity, node.getId(), createModificationNodeInfo("Child 1"), InsertMode.AFTER, null); + NetworkModificationNode child2 = networkModificationTreeService.createNode(studyEntity, node.getId(), createModificationNodeInfo("Child 2"), InsertMode.AFTER, null); // message for 3 modification nodes creation output.receive(TIMEOUT, STUDY_UPDATE_DESTINATION); diff --git a/src/test/java/org/gridsuite/study/server/service/StudyServiceDynamicSimulationTest.java b/src/test/java/org/gridsuite/study/server/service/StudyServiceDynamicSimulationTest.java index 013d13120..4600acd1e 100644 --- a/src/test/java/org/gridsuite/study/server/service/StudyServiceDynamicSimulationTest.java +++ b/src/test/java/org/gridsuite/study/server/service/StudyServiceDynamicSimulationTest.java @@ -65,6 +65,7 @@ class StudyServiceDynamicSimulationTest { private static final UUID STUDY_UUID = UUID.randomUUID(); private static final UUID NETWORK_UUID = UUID.randomUUID(); private static final UUID NODE_UUID = UUID.randomUUID(); + private static final UUID ROOTNETWORK_UUID = UUID.randomUUID(); private static final UUID RESULT_UUID = UUID.randomUUID(); @MockBean @@ -95,9 +96,9 @@ void setup() { // setup NetworkModificationTreeService mock // suppose always having an existing result in a previous run - given(networkModificationTreeService.getComputationResultUuid(any(UUID.class), eq(DYNAMIC_SIMULATION))).willReturn(Optional.of(RESULT_UUID)); - given(networkModificationTreeService.getVariantId(any(UUID.class))).willReturn(VARIANT_1_ID); - willDoNothing().given(networkModificationTreeService).updateComputationResultUuid(NODE_UUID, RESULT_UUID, DYNAMIC_SIMULATION); + given(networkModificationTreeService.getComputationResultUuid(any(UUID.class), any(UUID.class), eq(DYNAMIC_SIMULATION))).willReturn(RESULT_UUID); + given(networkModificationTreeService.getVariantId(any(UUID.class), any(UUID.class))).willReturn(VARIANT_1_ID); + willDoNothing().given(networkModificationTreeService).updateComputationResultUuid(NODE_UUID, ROOTNETWORK_UUID, RESULT_UUID, DYNAMIC_SIMULATION); // setup NotificationService mock willDoNothing().given(notificationService).emitStudyChanged(STUDY_UUID, NODE_UUID, UPDATE_TYPE_DYNAMIC_SIMULATION_STATUS); @@ -106,9 +107,9 @@ void setup() { @Test void testRunDynamicSimulation() { // setup DynamicSimulationService mock - given(dynamicSimulationService.runDynamicSimulation(eq(""), eq(STUDY_UUID), eq(NODE_UUID), any(), any(), any())).willReturn(RESULT_UUID); + given(dynamicSimulationService.runDynamicSimulation(eq(""), eq(STUDY_UUID), eq(NODE_UUID), eq(ROOTNETWORK_UUID), any(), any(), any())).willReturn(RESULT_UUID); willDoNothing().given(dynamicSimulationService).deleteResult(any(UUID.class)); - given(loadFlowService.getLoadFlowStatus(NODE_UUID)).willReturn(LoadFlowStatus.CONVERGED.name()); + given(loadFlowService.getLoadFlowStatus(NODE_UUID, ROOTNETWORK_UUID)).willReturn(LoadFlowStatus.CONVERGED.name()); // init parameters DynamicSimulationParametersInfos parameters = new DynamicSimulationParametersInfos(); @@ -117,7 +118,7 @@ void testRunDynamicSimulation() { parameters.setMapping(MAPPING_NAME_01); // call method to be tested - UUID resultUuid = studyService.runDynamicSimulation(STUDY_UUID, NODE_UUID, parameters, "testUserId"); + UUID resultUuid = studyService.runDynamicSimulation(STUDY_UUID, NODE_UUID, ROOTNETWORK_UUID, parameters, "testUserId"); // check result assertThat(resultUuid).isEqualTo(RESULT_UUID); @@ -133,10 +134,10 @@ void testGetDynamicSimulationTimeSeries() throws Exception { TimeSeries.createDouble("NETWORK__BUS____1_TN_Upu_value", index, 1.059970, 1.059970, 1.059970, 1.059970) )); - given(dynamicSimulationService.getTimeSeriesResult(NODE_UUID, null)).willReturn(timeSeries); + given(dynamicSimulationService.getTimeSeriesResult(NODE_UUID, ROOTNETWORK_UUID, null)).willReturn(timeSeries); // call method to be tested - String timeSeriesResultJson = TimeSeries.toJson(studyService.getDynamicSimulationTimeSeries(NODE_UUID, null)); + String timeSeriesResultJson = TimeSeries.toJson(studyService.getDynamicSimulationTimeSeries(NODE_UUID, ROOTNETWORK_UUID, null)); // --- check result --- // String timeSeriesExpectedJson = TimeSeries.toJson(timeSeries); @@ -156,10 +157,10 @@ void testGetDynamicSimulationTimeline() { new TimelineEventInfos(104396, "CLA_2_4", "CLA : arming by over-current constraint") ); - given(dynamicSimulationService.getTimelineResult(NODE_UUID)).willReturn(timelineEventInfosList); + given(dynamicSimulationService.getTimelineResult(NODE_UUID, ROOTNETWORK_UUID)).willReturn(timelineEventInfosList); // call method to be tested - List timelineEventInfosListResult = studyService.getDynamicSimulationTimeline(NODE_UUID); + List timelineEventInfosListResult = studyService.getDynamicSimulationTimeline(NODE_UUID, ROOTNETWORK_UUID); // --- check result --- // // must contain 4 timeline events @@ -169,10 +170,10 @@ void testGetDynamicSimulationTimeline() { @Test void testGetDynamicSimulationStatus() { // setup - given(dynamicSimulationService.getStatus(NODE_UUID)).willReturn(DynamicSimulationStatus.CONVERGED); + given(dynamicSimulationService.getStatus(NODE_UUID, ROOTNETWORK_UUID)).willReturn(DynamicSimulationStatus.CONVERGED); // call method to be tested - DynamicSimulationStatus status = studyService.getDynamicSimulationStatus(NODE_UUID); + DynamicSimulationStatus status = studyService.getDynamicSimulationStatus(NODE_UUID, ROOTNETWORK_UUID); // --- check result --- // LOGGER.info("Status expected = {}", DynamicSimulationStatus.CONVERGED.name()); diff --git a/src/test/java/org/gridsuite/study/server/service/dynamicsimulation/DynamicSimulationServiceTest.java b/src/test/java/org/gridsuite/study/server/service/dynamicsimulation/DynamicSimulationServiceTest.java index c678fc297..243909b3b 100644 --- a/src/test/java/org/gridsuite/study/server/service/dynamicsimulation/DynamicSimulationServiceTest.java +++ b/src/test/java/org/gridsuite/study/server/service/dynamicsimulation/DynamicSimulationServiceTest.java @@ -86,7 +86,8 @@ class DynamicSimulationServiceTest { // converged node private static final UUID NETWORK_UUID = UUID.randomUUID(); private static final UUID NODE_UUID = UUID.randomUUID(); - private static final UUID RESULT_UUID = UUID.randomUUID(); + private static final UUID ROOTNETWORK_UUID = UUID.randomUUID(); + public static final UUID RESULT_UUID = UUID.randomUUID(); private static final UUID TIME_SERIES_UUID = UUID.randomUUID(); private static final UUID TIMELINE_UUID = UUID.randomUUID(); @@ -124,20 +125,20 @@ class DynamicSimulationServiceTest { @BeforeEach void setup() { // setup networkModificationTreeService mock in all normal cases - given(networkModificationTreeService.getComputationResultUuid(NODE_UUID, ComputationType.DYNAMIC_SIMULATION)).willReturn(Optional.of(RESULT_UUID)); + given(networkModificationTreeService.getComputationResultUuid(NODE_UUID, ROOTNETWORK_UUID, ComputationType.DYNAMIC_SIMULATION)).willReturn(RESULT_UUID); } @Test void testRunDynamicSimulation() { given(networkService.getNetworkUuid(STUDY_UUID)).willReturn(NETWORK_UUID); - given(networkModificationTreeService.getVariantId(NODE_UUID)).willReturn(VARIANT_1_ID); - given(networkModificationTreeService.getReportUuid(NODE_UUID)).willReturn(REPORT_UUID); + given(networkModificationTreeService.getVariantId(NODE_UUID, ROOTNETWORK_UUID)).willReturn(VARIANT_1_ID); + given(networkModificationTreeService.getReportUuid(NODE_UUID, ROOTNETWORK_UUID)).willReturn(REPORT_UUID); // setup DynamicSimulationClient mock given(dynamicSimulationClient.run(eq(""), any(), eq(NETWORK_UUID), eq(VARIANT_1_ID), eq(new ReportInfos(REPORT_UUID, NODE_UUID)), any(), any())).willReturn(RESULT_UUID); // call method to be tested - UUID resultUuid = dynamicSimulationService.runDynamicSimulation("", STUDY_UUID, NODE_UUID, REPORT_UUID, null, "testUserId"); + UUID resultUuid = dynamicSimulationService.runDynamicSimulation("", STUDY_UUID, NODE_UUID, ROOTNETWORK_UUID, REPORT_UUID, null, "testUserId"); // check result assertThat(resultUuid).isEqualTo(RESULT_UUID); @@ -157,7 +158,7 @@ void testGetTimeSeriesMetadataList() throws Exception { given(timeSeriesClient.getTimeSeriesGroupMetadata(TIME_SERIES_UUID)).willReturn(timeSeriesGroupMetadata); // call method to be tested - List resultTimeSeriesMetadataList = dynamicSimulationService.getTimeSeriesMetadataList(NODE_UUID); + List resultTimeSeriesMetadataList = dynamicSimulationService.getTimeSeriesMetadataList(NODE_UUID, ROOTNETWORK_UUID); // check result // metadata must be identical to expected @@ -182,7 +183,7 @@ void testGetTimeSeriesResult() { given(timeSeriesClient.getTimeSeriesGroup(TIME_SERIES_UUID, null)).willReturn(timeSeries); // call method to be tested - List timeSeriesResult = dynamicSimulationService.getTimeSeriesResult(NODE_UUID, null); + List timeSeriesResult = dynamicSimulationService.getTimeSeriesResult(NODE_UUID, ROOTNETWORK_UUID, null); // check result // must contain two elements @@ -205,7 +206,7 @@ void testGetTimeSeriesResultGivenBadType() { given(timeSeriesClient.getTimeSeriesGroup(TIME_SERIES_UUID, null)).willReturn(timeSeries); // call method to be tested - assertThrows(StudyException.class, () -> dynamicSimulationService.getTimeSeriesResult(NODE_UUID, null)); + assertThrows(StudyException.class, () -> dynamicSimulationService.getTimeSeriesResult(NODE_UUID, ROOTNETWORK_UUID, null)); } @Test @@ -236,7 +237,7 @@ void testGetTimelineResult() { given(timeSeriesClient.getTimeSeriesGroup(TIMELINE_UUID, null)).willReturn(timelineSeries); // call method to be tested - List timelineResult = dynamicSimulationService.getTimelineResult(NODE_UUID); + List timelineResult = dynamicSimulationService.getTimelineResult(NODE_UUID, ROOTNETWORK_UUID); // check result // must contain 4 timeline events @@ -257,7 +258,7 @@ void testGetTimelineResultGivenBadType() throws Exception { // call method to be tested assertThatExceptionOfType(StudyException.class).isThrownBy(() -> - dynamicSimulationService.getTimelineResult(NODE_UUID) + dynamicSimulationService.getTimelineResult(NODE_UUID, ROOTNETWORK_UUID) ).withMessage("Timelines can not be a type: %s, expected type: %s", timelines.get(0).getClass().getSimpleName(), StringTimeSeries.class.getSimpleName()); @@ -285,7 +286,7 @@ void testGetTimelineResultGivenBadType() throws Exception { // call method to be tested assertThatExceptionOfType(StudyException.class).isThrownBy(() -> - dynamicSimulationService.getTimelineResult(NODE_UUID) + dynamicSimulationService.getTimelineResult(NODE_UUID, ROOTNETWORK_UUID) ).withMessage("Error while deserializing timeline event: %s", objectMapper.writeValueAsString(timelineEventInfosList.get(0))); } @@ -295,7 +296,7 @@ void testGetStatus() { given(dynamicSimulationClient.getStatus(RESULT_UUID)).willReturn(DynamicSimulationStatus.CONVERGED); // call method to be tested - DynamicSimulationStatus status = dynamicSimulationService.getStatus(NODE_UUID); + DynamicSimulationStatus status = dynamicSimulationService.getStatus(NODE_UUID, ROOTNETWORK_UUID); // check result // status must be "CONVERGED" @@ -316,17 +317,17 @@ void testDeleteResult() { void testAssertDynamicSimulationNotRunning() { // test not running - assertDoesNotThrow(() -> dynamicSimulationService.assertDynamicSimulationNotRunning(NODE_UUID)); + assertDoesNotThrow(() -> dynamicSimulationService.assertDynamicSimulationNotRunning(NODE_UUID, ROOTNETWORK_UUID)); } @Test void testAssertDynamicSimulationRunning() { // setup for running node given(dynamicSimulationClient.getStatus(RESULT_UUID_RUNNING)).willReturn(DynamicSimulationStatus.RUNNING); - given(networkModificationTreeService.getComputationResultUuid(NODE_UUID_RUNNING, ComputationType.DYNAMIC_SIMULATION)).willReturn(Optional.of(RESULT_UUID_RUNNING)); + given(networkModificationTreeService.getComputationResultUuid(NODE_UUID_RUNNING, ROOTNETWORK_UUID, ComputationType.DYNAMIC_SIMULATION)).willReturn(RESULT_UUID_RUNNING); // test running - assertThrows(StudyException.class, () -> dynamicSimulationService.assertDynamicSimulationNotRunning(NODE_UUID_RUNNING)); + assertThrows(StudyException.class, () -> dynamicSimulationService.assertDynamicSimulationNotRunning(NODE_UUID_RUNNING, ROOTNETWORK_UUID)); } @Test diff --git a/src/test/java/org/gridsuite/study/server/utils/TestUtils.java b/src/test/java/org/gridsuite/study/server/utils/TestUtils.java index b38c398af..6c9017b12 100644 --- a/src/test/java/org/gridsuite/study/server/utils/TestUtils.java +++ b/src/test/java/org/gridsuite/study/server/utils/TestUtils.java @@ -18,6 +18,7 @@ import org.gridsuite.study.server.networkmodificationtree.dto.NetworkModificationNode; import org.gridsuite.study.server.networkmodificationtree.dto.NodeBuildStatus; import org.gridsuite.study.server.repository.StudyEntity; +import org.gridsuite.study.server.repository.rootnetwork.RootNetworkEntity; import org.gridsuite.study.server.repository.nonevacuatedenergy.NonEvacuatedEnergyParametersEntity; import org.gridsuite.study.server.repository.voltageinit.StudyVoltageInitParametersEntity; import org.junit.platform.commons.util.StringUtils; @@ -80,7 +81,8 @@ public static Set getRequestsDone(int n, MockWebServer server) { }).collect(Collectors.toSet()); } - public static StudyEntity createDummyStudy(UUID networkUuid, UUID caseUuid, String caseFormat, + //TODO: WHY is casename now mandatory ? there was @NotNull before as well + public static StudyEntity createDummyStudy(UUID networkUuid, String networkId, UUID caseUuid, String caseFormat, String caseName, UUID importReportUuid, UUID loadFlowParametersUuid, UUID shortCircuitParametersUuid, UUID voltageInitParametersUuid, @@ -88,9 +90,7 @@ public static StudyEntity createDummyStudy(UUID networkUuid, UUID caseUuid, Stri UUID sensitivityParametersUuid, NonEvacuatedEnergyParametersEntity nonEvacuatedEnergyParametersEntity, boolean applyModifications) { - return StudyEntity.builder().id(UUID.randomUUID()).caseFormat(caseFormat).caseUuid(caseUuid) - .networkId("netId") - .networkUuid(networkUuid) + StudyEntity studyEntity = StudyEntity.builder().id(UUID.randomUUID()) .loadFlowParametersUuid(loadFlowParametersUuid) .shortCircuitParametersUuid(shortCircuitParametersUuid) .voltageInitParametersUuid(voltageInitParametersUuid) @@ -99,32 +99,37 @@ public static StudyEntity createDummyStudy(UUID networkUuid, UUID caseUuid, Stri .nonEvacuatedEnergyParameters(nonEvacuatedEnergyParametersEntity) .voltageInitParameters(new StudyVoltageInitParametersEntity(applyModifications)) .build(); + RootNetworkEntity rootNetworkEntity = RootNetworkEntity.builder().caseFormat(caseFormat).caseUuid(caseUuid).caseName(caseName).networkId(networkId).networkUuid(networkUuid).reportUuid(importReportUuid).build(); + studyEntity.addRootNetwork(rootNetworkEntity); + + return studyEntity; } - public static StudyEntity createDummyStudy(UUID networkUuid, UUID caseUuid, String caseFormat, + public static StudyEntity createDummyStudy(UUID networkUuid, String networkId, UUID caseUuid, String caseFormat, String caseName, UUID reportUuid, UUID loadFlowParametersUuid, UUID shortCircuitParametersUuid, UUID securityAnalysisParametersUuid, UUID sensitivityParametersUuid, NonEvacuatedEnergyParametersEntity nonEvacuatedEnergyParametersEntity) { - return StudyEntity.builder().id(UUID.randomUUID()).caseFormat(caseFormat).caseUuid(caseUuid) - .networkId("netId") - .networkUuid(networkUuid) + StudyEntity studyEntity = StudyEntity.builder().id(UUID.randomUUID()) .loadFlowParametersUuid(loadFlowParametersUuid) .shortCircuitParametersUuid(shortCircuitParametersUuid) .securityAnalysisParametersUuid(securityAnalysisParametersUuid) .sensitivityAnalysisParametersUuid(sensitivityParametersUuid) .nonEvacuatedEnergyParameters(nonEvacuatedEnergyParametersEntity) .build(); + RootNetworkEntity rootNetworkEntity = RootNetworkEntity.builder().caseFormat(caseFormat).caseUuid(caseUuid).caseName(caseName).networkId(networkId).networkUuid(networkUuid).reportUuid(reportUuid).build(); + studyEntity.addRootNetwork(rootNetworkEntity); + return studyEntity; } - public static StudyEntity createDummyStudy(UUID networkUuid, UUID caseUuid, String caseName, String caseFormat) { - return StudyEntity.builder().id(UUID.randomUUID()).caseFormat(caseFormat).caseUuid(caseUuid) - .caseName(caseName) - .networkId("netId") - .networkUuid(networkUuid) + public static StudyEntity createDummyStudy(UUID networkUuid, UUID caseUuid, String caseName, String caseFormat, UUID reportUuid) { + StudyEntity studyEntity = StudyEntity.builder().id(UUID.randomUUID()) .shortCircuitParametersUuid(UUID.randomUUID()) .build(); + studyEntity.addRootNetwork(RootNetworkEntity.builder().caseFormat(caseFormat).caseUuid(caseUuid).caseName(caseName).networkId("netId").networkUuid(networkUuid).reportUuid(reportUuid).build()); + + return studyEntity; } public static NetworkModificationNode createModificationNodeInfo(String name) { diff --git a/src/test/java/org/gridsuite/study/server/utils/WireMockUtils.java b/src/test/java/org/gridsuite/study/server/utils/WireMockUtils.java index 4c39f30e6..6caf24614 100644 --- a/src/test/java/org/gridsuite/study/server/utils/WireMockUtils.java +++ b/src/test/java/org/gridsuite/study/server/utils/WireMockUtils.java @@ -316,7 +316,7 @@ public void verifyCaseExists(UUID stubUuid, String caseUuid) { removeRequestForStub(stubUuid, 1); } - public UUID stubImportNetwork(String caseUuid, Map importParameters, String networkUuid, String networkId, String caseFormat, CountDownLatch countDownLatch) { + public UUID stubImportNetwork(String caseUuid, Map importParameters, String networkUuid, String networkId, String caseFormat, String caseName, CountDownLatch countDownLatch) { UUID importNetworkStubId = wireMock.stubFor(WireMock.post(WireMock.urlPathEqualTo("/v1/networks")) .withQueryParam("caseUuid", WireMock.equalTo(caseUuid)) .withQueryParam("variantId", WireMock.equalTo(FIRST_VARIANT_ID)) @@ -329,6 +329,7 @@ public UUID stubImportNetwork(String caseUuid, Map importParamet "networkUuid", networkUuid, "networkId", networkId, "caseFormat", caseFormat, + "caseName", caseName, "importParameters", importParameters, "latch", countDownLatch )