Skip to content

Commit 16ebd8a

Browse files
authored
Debug computation mode (#19)
Signed-off-by: Thang PHAM <[email protected]>
1 parent b129945 commit 16ebd8a

18 files changed

+226
-103
lines changed

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@
4444
<properties>
4545
<gridsuite-dependencies.version>42.0.0</gridsuite-dependencies.version>
4646
<!-- FIXME to remove at next upgrade of gridsuite-dependencies -->
47-
<gridsuite-computation.version>1.0.0</gridsuite-computation.version>
47+
<gridsuite-computation.version>1.1.0</gridsuite-computation.version>
4848
<!-- FIXME to remove at next upgrade of powsybl-ws-dependencies -->
49-
<powsybl-ws-commons.version>1.28.0</powsybl-ws-commons.version>
49+
<powsybl-ws-commons.version>1.28.1</powsybl-ws-commons.version>
5050

5151
<jib.from.image>powsybl/java-dynawo:3.0.0</jib.from.image>
5252
<liquibase-hibernate-package>org.gridsuite.dynamicsecurityanalysis.server</liquibase-hibernate-package>

src/main/java/org/gridsuite/dynamicsecurityanalysis/server/controller/DynamicSecurityAnalysisController.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.gridsuite.dynamicsecurityanalysis.server.service.DynamicSecurityAnalysisService;
1919
import org.gridsuite.dynamicsecurityanalysis.server.service.ParametersService;
2020
import org.gridsuite.dynamicsecurityanalysis.server.service.contexts.DynamicSecurityAnalysisRunContext;
21+
import org.springframework.core.io.Resource;
2122
import org.springframework.http.MediaType;
2223
import org.springframework.http.ResponseEntity;
2324
import org.springframework.web.bind.annotation.*;
@@ -61,6 +62,7 @@ public ResponseEntity<UUID> run(@PathVariable("networkUuid") UUID networkUuid,
6162
@RequestParam(name = REPORTER_ID_HEADER, required = false) String reportName,
6263
@RequestParam(name = REPORT_TYPE_HEADER, required = false, defaultValue = "DynamicSecurityAnalysis") String reportType,
6364
@RequestParam(name = HEADER_PROVIDER, required = false) String provider,
65+
@RequestParam(name = "debug", required = false, defaultValue = "false") boolean debug,
6466
@RequestParam(name = "dynamicSimulationResultUuid") UUID dynamicSimulationResultUuid,
6567
@RequestParam(name = "parametersUuid") UUID parametersUuid,
6668
@RequestHeader(HEADER_USER_ID) String userId) {
@@ -73,7 +75,8 @@ public ResponseEntity<UUID> run(@PathVariable("networkUuid") UUID networkUuid,
7375
ReportInfos.builder().reportUuid(reportId).reporterId(reportName).computationType(reportType).build(),
7476
userId,
7577
dynamicSimulationResultUuid,
76-
parametersUuid);
78+
parametersUuid,
79+
debug);
7780

7881
UUID resultUuid = dynamicSecurityAnalysisService.runAndSaveResult(dynamicSecurityAnalysisRunContext);
7982
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(resultUuid);
@@ -138,4 +141,13 @@ public ResponseEntity<List<String>> getProviders() {
138141
public ResponseEntity<String> getDefaultProvider() {
139142
return ResponseEntity.ok().body(dynamicSecurityAnalysisService.getDefaultProvider());
140143
}
144+
145+
@GetMapping(value = "/results/{resultUuid}/download-debug-file", produces = "application/json")
146+
@Operation(summary = "Download a dynamic security analysis debug file")
147+
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Dynamic security analysis debug file"),
148+
@ApiResponse(responseCode = "404", description = "Dynamic security analysis debug file has not been found")})
149+
public ResponseEntity<Resource> downloadDebugFile(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid) {
150+
return dynamicSecurityAnalysisService.downloadDebugFile(resultUuid);
151+
}
152+
141153
}

src/main/java/org/gridsuite/dynamicsecurityanalysis/server/entities/DynamicSecurityAnalysisResultEntity.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
package org.gridsuite.dynamicsecurityanalysis.server.entities;
99

1010
import jakarta.persistence.*;
11+
import lombok.AllArgsConstructor;
1112
import lombok.Getter;
1213
import lombok.NoArgsConstructor;
1314
import lombok.Setter;
@@ -22,14 +23,10 @@
2223
@Setter
2324
@Table(name = "dynamic_security_analysis_result")
2425
@NoArgsConstructor
26+
@AllArgsConstructor
2527
@Entity
2628
public class DynamicSecurityAnalysisResultEntity {
2729

28-
public DynamicSecurityAnalysisResultEntity(UUID id, DynamicSecurityAnalysisStatus status) {
29-
this.id = id;
30-
this.status = status;
31-
}
32-
3330
@Id
3431
@Column(name = "result_uuid")
3532
private UUID id;
@@ -38,4 +35,7 @@ public DynamicSecurityAnalysisResultEntity(UUID id, DynamicSecurityAnalysisStatu
3835
@Enumerated(EnumType.STRING)
3936
private DynamicSecurityAnalysisStatus status;
4037

38+
@Column(name = "debugFileLocation")
39+
private String debugFileLocation;
40+
4141
}

src/main/java/org/gridsuite/dynamicsecurityanalysis/server/repositories/DynamicSecurityAnalysisResultRepository.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99

1010
import org.gridsuite.dynamicsecurityanalysis.server.entities.DynamicSecurityAnalysisResultEntity;
1111
import org.springframework.data.jpa.repository.JpaRepository;
12+
import org.springframework.data.jpa.repository.Modifying;
13+
import org.springframework.data.jpa.repository.Query;
14+
import org.springframework.data.repository.query.Param;
1215
import org.springframework.stereotype.Repository;
1316

1417
import java.util.UUID;
@@ -18,4 +21,8 @@
1821
*/
1922
@Repository
2023
public interface DynamicSecurityAnalysisResultRepository extends JpaRepository<DynamicSecurityAnalysisResultEntity, UUID> {
24+
@Modifying
25+
@Query("UPDATE DynamicSecurityAnalysisResultEntity r SET r.debugFileLocation = :debugFileLocation WHERE r.id = :resultUuid")
26+
int updateDebugFileLocation(@Param("resultUuid") UUID resultUuid, @Param("debugFileLocation") String debugFileLocation);
27+
2128
}

src/main/java/org/gridsuite/dynamicsecurityanalysis/server/service/DynamicSecurityAnalysisResultService.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
package org.gridsuite.dynamicsecurityanalysis.server.service;
99

10-
import jakarta.transaction.Transactional;
1110
import org.gridsuite.computation.service.AbstractComputationResultService;
1211
import org.gridsuite.dynamicsecurityanalysis.server.DynamicSecurityAnalysisException;
1312
import org.gridsuite.dynamicsecurityanalysis.server.dto.DynamicSecurityAnalysisStatus;
@@ -16,6 +15,7 @@
1615
import org.slf4j.Logger;
1716
import org.slf4j.LoggerFactory;
1817
import org.springframework.stereotype.Service;
18+
import org.springframework.transaction.annotation.Transactional;
1919

2020
import java.util.List;
2121
import java.util.Objects;
@@ -43,7 +43,7 @@ public DynamicSecurityAnalysisResultService(DynamicSecurityAnalysisResultReposit
4343
public void insertStatus(List<UUID> resultUuids, DynamicSecurityAnalysisStatus status) {
4444
Objects.requireNonNull(resultUuids);
4545
resultRepository.saveAll(resultUuids.stream()
46-
.map(uuid -> new DynamicSecurityAnalysisResultEntity(uuid, status)).toList());
46+
.map(uuid -> new DynamicSecurityAnalysisResultEntity(uuid, status, null)).toList());
4747
}
4848

4949
@Transactional
@@ -65,6 +65,16 @@ public void updateResult(UUID resultUuid, DynamicSecurityAnalysisStatus status)
6565
}
6666

6767
@Override
68+
@Transactional
69+
public void saveDebugFileLocation(UUID resultUuid, String debugFilePath) {
70+
resultRepository.findById(resultUuid).ifPresentOrElse(
71+
(var resultEntity) -> resultRepository.updateDebugFileLocation(resultUuid, debugFilePath),
72+
() -> resultRepository.save(new DynamicSecurityAnalysisResultEntity(resultUuid, DynamicSecurityAnalysisStatus.NOT_DONE, debugFilePath))
73+
);
74+
}
75+
76+
@Override
77+
@Transactional
6878
public void delete(UUID resultUuid) {
6979
Objects.requireNonNull(resultUuid);
7080
resultRepository.deleteById(resultUuid);
@@ -77,10 +87,20 @@ public void deleteAll() {
7787
}
7888

7989
@Override
90+
@Transactional(readOnly = true)
8091
public DynamicSecurityAnalysisStatus findStatus(UUID resultUuid) {
8192
Objects.requireNonNull(resultUuid);
8293
return resultRepository.findById(resultUuid)
8394
.map(DynamicSecurityAnalysisResultEntity::getStatus)
8495
.orElse(null);
8596
}
97+
98+
@Override
99+
@Transactional(readOnly = true)
100+
public String findDebugFileLocation(UUID resultUuid) {
101+
Objects.requireNonNull(resultUuid);
102+
return resultRepository.findById(resultUuid)
103+
.map(DynamicSecurityAnalysisResultEntity::getDebugFileLocation)
104+
.orElse(null);
105+
}
86106
}

src/main/java/org/gridsuite/dynamicsecurityanalysis/server/service/DynamicSecurityAnalysisService.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.fasterxml.jackson.databind.ObjectMapper;
1010
import com.powsybl.network.store.client.NetworkStoreService;
1111
import com.powsybl.security.dynamic.DynamicSecurityAnalysisProvider;
12+
import org.gridsuite.computation.s3.ComputationS3Service;
1213
import org.gridsuite.computation.service.AbstractComputationService;
1314
import org.gridsuite.computation.service.NotificationService;
1415
import org.gridsuite.computation.service.UuidGeneratorService;
@@ -36,8 +37,9 @@ public DynamicSecurityAnalysisService(
3637
ObjectMapper objectMapper,
3738
UuidGeneratorService uuidGeneratorService,
3839
DynamicSecurityAnalysisResultService dynamicSecurityAnalysisResultService,
40+
ComputationS3Service computationS3Service,
3941
@Value("${dynamic-security-analysis.default-provider}") String defaultProvider) {
40-
super(notificationService, dynamicSecurityAnalysisResultService, objectMapper, uuidGeneratorService, defaultProvider);
42+
super(notificationService, dynamicSecurityAnalysisResultService, computationS3Service, objectMapper, uuidGeneratorService, defaultProvider);
4143
}
4244

4345
@Override

src/main/java/org/gridsuite/dynamicsecurityanalysis/server/service/DynamicSecurityAnalysisWorkerService.java

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import com.powsybl.security.dynamic.DynamicSecurityAnalysisRunParameters;
3030
import com.powsybl.security.results.PostContingencyResult;
3131
import org.apache.commons.collections4.CollectionUtils;
32+
import org.gridsuite.computation.s3.ComputationS3Service;
3233
import org.gridsuite.computation.service.*;
3334
import org.gridsuite.dynamicsecurityanalysis.server.DynamicSecurityAnalysisException;
3435
import org.gridsuite.dynamicsecurityanalysis.server.dto.DynamicSecurityAnalysisStatus;
@@ -82,10 +83,11 @@ public DynamicSecurityAnalysisWorkerService(NetworkStoreService networkStoreServ
8283
DynamicSecurityAnalysisObserver observer,
8384
ObjectMapper objectMapper,
8485
DynamicSecurityAnalysisResultService dynamicSecurityAnalysisResultService,
86+
ComputationS3Service computationS3Service,
8587
DynamicSimulationClient dynamicSimulationClient,
8688
ActionsClient actionsClient,
8789
ParametersService parametersService) {
88-
super(networkStoreService, notificationService, reportService, dynamicSecurityAnalysisResultService, executionService, observer, objectMapper);
90+
super(networkStoreService, notificationService, reportService, dynamicSecurityAnalysisResultService, computationS3Service, executionService, observer, objectMapper);
8991
this.dynamicSimulationClient = Objects.requireNonNull(dynamicSimulationClient);
9092
this.actionsClient = Objects.requireNonNull(actionsClient);
9193
this.parametersService = Objects.requireNonNull(parametersService);
@@ -167,6 +169,9 @@ public void preRun(DynamicSecurityAnalysisRunContext runContext) {
167169

168170
// create a new dynamic security analysis parameters
169171
DynamicSecurityAnalysisParameters parameters = new DynamicSecurityAnalysisParameters();
172+
if (runContext.getDebugDir() != null) {
173+
parameters.setDebugDir(runContext.getDebugDir().toString());
174+
}
170175
parameters.setDynamicSimulationParameters(dynamicSimulationParameters);
171176

172177
// set start and stop times
@@ -251,33 +256,36 @@ protected void clean(AbstractResultContext<DynamicSecurityAnalysisRunContext> re
251256
super.clean(resultContext);
252257
// clean working directory
253258
Path workDir = resultContext.getRunContext().getWorkDir();
254-
removeWorkingDirectory(workDir);
259+
removeDirectory(workDir);
260+
}
261+
262+
@Override
263+
protected void processDebug(AbstractResultContext<DynamicSecurityAnalysisRunContext> resultContext) {
264+
// copy all content from working directory into debug directory
265+
DynamicSecurityAnalysisRunContext runContext = resultContext.getRunContext();
266+
if (runContext.getWorkDir() != null && runContext.getDebugDir() != null) {
267+
try {
268+
FileUtil.copyDir(runContext.getWorkDir(), runContext.getDebugDir());
269+
} catch (IOException e) {
270+
LOGGER.error("{}: Error occurred while copying directory {} to directory {} => {}",
271+
getComputationType(), runContext.getWorkDir().toAbsolutePath(), runContext.getDebugDir().toAbsolutePath(), e.getMessage());
272+
}
273+
}
274+
super.processDebug(resultContext);
255275
}
256276

257277
private Path createWorkingDirectory() {
258278
Path workDir;
259279
Path localDir = getComputationManager().getLocalDir();
260280
try {
261-
workDir = Files.createTempDirectory(localDir, "dynamic_security_analysis_");
281+
workDir = Files.createTempDirectory(localDir, buildComputationDirPrefix());
262282
} catch (IOException e) {
263283
throw new DynamicSecurityAnalysisException(DUMP_FILE_ERROR, String.format("Error occurred while creating a working directory inside the local directory %s",
264284
localDir.toAbsolutePath()));
265285
}
266286
return workDir;
267287
}
268288

269-
private void removeWorkingDirectory(Path workDir) {
270-
if (workDir != null) {
271-
try {
272-
FileUtil.removeDir(workDir);
273-
} catch (IOException e) {
274-
LOGGER.error(String.format("%s: Error occurred while cleaning working directory at %s", getComputationType(), workDir.toAbsolutePath()), e);
275-
}
276-
} else {
277-
LOGGER.info("{}: No working directory to clean", getComputationType());
278-
}
279-
}
280-
281289
// --- TODO remove these reports when powsybl-dynawo implements --- //
282290
private static void enrichContingenciesTimelineReport(SecurityAnalysisReport securityAnalysisReport, ReportNode reportNode) {
283291
for (PostContingencyResult postContingencyResult : securityAnalysisReport.getResult().getPostContingencyResults()) {

src/main/java/org/gridsuite/dynamicsecurityanalysis/server/service/ParametersService.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
import com.fasterxml.jackson.core.type.TypeReference;
1010
import com.fasterxml.jackson.databind.ObjectMapper;
11-
import com.powsybl.commons.io.FileUtil;
1211
import com.powsybl.dynamicsimulation.DynamicSimulationParameters;
1312
import com.powsybl.dynamicsimulation.DynamicSimulationProvider;
1413
import com.powsybl.dynawo.DumpFileParameters;
@@ -57,7 +56,8 @@ public ParametersService(@Value("${dynamic-security-analysis.default-provider}")
5756
public DynamicSecurityAnalysisRunContext createRunContext(UUID networkUuid, String variantId, String receiver,
5857
String provider, ReportInfos reportInfos, String userId,
5958
UUID dynamicSimulationResultUuid,
60-
UUID dynamicSecurityAnalysisParametersUuid) {
59+
UUID dynamicSecurityAnalysisParametersUuid,
60+
boolean debug) {
6161

6262
// get parameters from the local database
6363
DynamicSecurityAnalysisParametersInfos dynamicSecurityAnalysisParametersInfos = getParameters(dynamicSecurityAnalysisParametersUuid);
@@ -70,6 +70,7 @@ public DynamicSecurityAnalysisRunContext createRunContext(UUID networkUuid, Stri
7070
.reportInfos(reportInfos)
7171
.userId(userId)
7272
.parameters(dynamicSecurityAnalysisParametersInfos)
73+
.debug(debug)
7374
.build();
7475
runContext.setDynamicSimulationResultUuid(dynamicSimulationResultUuid);
7576

@@ -93,11 +94,9 @@ public DynamicSecurityAnalysisRunContext createRunContext(UUID networkUuid, Stri
9394
// --- Dynamic simulation result related methods --- //
9495

9596
public void setupDumpParameters(Path workDir, DynamicSimulationParameters dynamicSimulationParameters, byte[] zippedOutputState) {
96-
Path dumpDir = workDir.resolve("dump");
97-
FileUtil.createDirectory(dumpDir);
98-
Path dumpFile = unZipDumpFile(dumpDir, zippedOutputState);
97+
Path dumpFile = unZipDumpFile(workDir, zippedOutputState);
9998
DynawoSimulationParameters dynawoSimulationParameters = dynamicSimulationParameters.getExtension(DynawoSimulationParameters.class);
100-
dynawoSimulationParameters.setDumpFileParameters(DumpFileParameters.createImportDumpFileParameters(dumpDir, dumpFile.getFileName().toString()));
99+
dynawoSimulationParameters.setDumpFileParameters(DumpFileParameters.createImportDumpFileParameters(workDir, dumpFile.getFileName().toString()));
101100
}
102101

103102
private Path unZipDumpFile(Path dumpDir, byte[] zippedOutputState) {

src/main/java/org/gridsuite/dynamicsecurityanalysis/server/service/contexts/DynamicSecurityAnalysisResultContext.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public static DynamicSecurityAnalysisResultContext fromMessage(Message<String> m
5555
String reporterId = (String) headers.get(REPORTER_ID_HEADER);
5656
String reportType = (String) headers.get(REPORT_TYPE_HEADER);
5757
String userId = (String) headers.get(HEADER_USER_ID);
58+
Boolean debug = (Boolean) headers.get(HEADER_DEBUG);
5859

5960
DynamicSecurityAnalysisRunContext runContext = DynamicSecurityAnalysisRunContext.builder()
6061
.networkUuid(networkUuid)
@@ -64,6 +65,7 @@ public static DynamicSecurityAnalysisResultContext fromMessage(Message<String> m
6465
.reportInfos(ReportInfos.builder().reportUuid(reportUuid).reporterId(reporterId).computationType(reportType).build())
6566
.userId(userId)
6667
.parameters(parametersInfos)
68+
.debug(debug)
6769
.build();
6870

6971
// specific headers for dynamic simulation

src/main/java/org/gridsuite/dynamicsecurityanalysis/server/service/contexts/DynamicSecurityAnalysisRunContext.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ public class DynamicSecurityAnalysisRunContext extends AbstractComputationRunCon
3838

3939
@Builder
4040
public DynamicSecurityAnalysisRunContext(UUID networkUuid, String variantId, String receiver, String provider,
41-
ReportInfos reportInfos, String userId, DynamicSecurityAnalysisParametersInfos parameters) {
42-
super(networkUuid, variantId, receiver, reportInfos, userId, provider, parameters);
41+
ReportInfos reportInfos, String userId, DynamicSecurityAnalysisParametersInfos parameters, Boolean debug) {
42+
super(networkUuid, variantId, receiver, reportInfos, userId, provider, parameters, debug);
4343
}
4444
}
4545

0 commit comments

Comments
 (0)