diff --git a/pom.xml b/pom.xml index da61530..a606c0c 100644 --- a/pom.xml +++ b/pom.xml @@ -51,9 +51,9 @@ 42.0.0 - 1.0.0 + 1.1.0 - 1.28.0 + 1.28.1 0.14.0 0.13.0 5.0.0-alpha.14 diff --git a/src/main/java/org/gridsuite/voltageinit/server/VoltageInitController.java b/src/main/java/org/gridsuite/voltageinit/server/VoltageInitController.java index a69a50f..f1f6c9e 100644 --- a/src/main/java/org/gridsuite/voltageinit/server/VoltageInitController.java +++ b/src/main/java/org/gridsuite/voltageinit/server/VoltageInitController.java @@ -11,20 +11,19 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; - import org.gridsuite.voltageinit.server.dto.VoltageInitResult; import org.gridsuite.voltageinit.server.dto.VoltageInitStatus; import org.gridsuite.voltageinit.server.service.VoltageInitRunContext; import org.gridsuite.voltageinit.server.service.VoltageInitService; +import org.springframework.core.io.Resource; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import java.util.List; -import java.util.UUID; - import java.net.URLDecoder; import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.UUID; import static org.gridsuite.computation.service.NotificationService.HEADER_USER_ID; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; @@ -52,9 +51,10 @@ public ResponseEntity runAndSave(@Parameter(description = "Network UUID") @Parameter(description = "reportUuid") @RequestParam(name = "reportUuid", required = false) UUID reportUuid, @Parameter(description = "reporterId") @RequestParam(name = "reporterId", required = false) String reporterId, @Parameter(description = "The type name for the report") @RequestParam(name = "reportType", required = false, defaultValue = "VoltageInit") String reportType, + @Parameter(description = "Debug") @RequestParam(name = "debug", required = false, defaultValue = "false") boolean debug, @Parameter(description = "parametersUuid") @RequestParam(name = "parametersUuid", required = false) UUID parametersUuid, @RequestHeader(HEADER_USER_ID) String userId) { - VoltageInitRunContext runContext = new VoltageInitRunContext(networkUuid, variantId, receiver, reportUuid, reporterId, reportType, userId, parametersUuid); + VoltageInitRunContext runContext = new VoltageInitRunContext(networkUuid, variantId, receiver, reportUuid, reporterId, reportType, userId, parametersUuid, debug); UUID resultUuid = voltageInitService.runAndSaveResult(runContext); return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(resultUuid); } @@ -124,4 +124,12 @@ public ResponseEntity resetModificationsGroupUuidInResult(@Parameter(descr voltageInitService.resetModificationsGroupUuid(resultUuid); return ResponseEntity.ok().build(); } + + @GetMapping(value = "/results/{resultUuid}/download-debug-file", produces = "application/json") + @Operation(summary = "Download a voltage init debug file") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Voltage init debug file"), + @ApiResponse(responseCode = "404", description = "Voltage init debug file has not been found")}) + public ResponseEntity downloadDebugFile(@Parameter(description = "Result UUID") @PathVariable("resultUuid") UUID resultUuid) { + return voltageInitService.downloadDebugFile(resultUuid); + } } diff --git a/src/main/java/org/gridsuite/voltageinit/server/entities/VoltageInitResultEntity.java b/src/main/java/org/gridsuite/voltageinit/server/entities/VoltageInitResultEntity.java index 7d0770e..00f4918 100644 --- a/src/main/java/org/gridsuite/voltageinit/server/entities/VoltageInitResultEntity.java +++ b/src/main/java/org/gridsuite/voltageinit/server/entities/VoltageInitResultEntity.java @@ -6,25 +6,17 @@ */ package org.gridsuite.voltageinit.server.entities; -import java.time.Instant; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import jakarta.persistence.CollectionTable; -import jakarta.persistence.Column; -import jakarta.persistence.ElementCollection; -import jakarta.persistence.Entity; -import jakarta.persistence.ForeignKey; -import jakarta.persistence.Id; -import jakarta.persistence.Index; -import jakarta.persistence.Table; - +import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import java.time.Instant; +import java.util.List; +import java.util.Map; +import java.util.UUID; + /** * @author Ayoub LABIDI */ @@ -62,4 +54,7 @@ public class VoltageInitResultEntity { @Column private Double reactiveSlacksThreshold; + + @Column(name = "debug_file_location") + private String debugFileLocation; } diff --git a/src/main/java/org/gridsuite/voltageinit/server/repository/ResultRepository.java b/src/main/java/org/gridsuite/voltageinit/server/repository/ResultRepository.java index 273ea3c..562b896 100644 --- a/src/main/java/org/gridsuite/voltageinit/server/repository/ResultRepository.java +++ b/src/main/java/org/gridsuite/voltageinit/server/repository/ResultRepository.java @@ -6,13 +6,16 @@ */ package org.gridsuite.voltageinit.server.repository; -import java.util.Optional; -import java.util.UUID; - import org.gridsuite.voltageinit.server.entities.VoltageInitResultEntity; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import java.util.Optional; +import java.util.UUID; + /** * @author Ayoub LABIDI */ @@ -23,4 +26,8 @@ public interface ResultRepository extends JpaRepository findByResultUuid(UUID resultUuid); void deleteByResultUuid(UUID resultUuid); + + @Modifying + @Query("UPDATE VoltageInitResultEntity r SET r.debugFileLocation = :debugFileLocation WHERE r.resultUuid = :resultUuid") + int updateDebugFileLocation(@Param("resultUuid") UUID resultUuid, @Param("debugFileLocation") String debugFileLocation); } diff --git a/src/main/java/org/gridsuite/voltageinit/server/service/VoltageInitResultContext.java b/src/main/java/org/gridsuite/voltageinit/server/service/VoltageInitResultContext.java index 9571fb6..d0c866e 100644 --- a/src/main/java/org/gridsuite/voltageinit/server/service/VoltageInitResultContext.java +++ b/src/main/java/org/gridsuite/voltageinit/server/service/VoltageInitResultContext.java @@ -18,8 +18,7 @@ import java.io.UncheckedIOException; import java.util.*; -import static org.gridsuite.computation.service.NotificationService.HEADER_RECEIVER; -import static org.gridsuite.computation.service.NotificationService.HEADER_USER_ID; +import static org.gridsuite.computation.service.NotificationService.*; /** * @author Etienne Homer @@ -51,6 +50,7 @@ public static VoltageInitResultContext fromMessage(Message message, Obje String variantId = (String) headers.get(VARIANT_ID_HEADER); String receiver = (String) headers.get(HEADER_RECEIVER); String userId = (String) headers.get(HEADER_USER_ID); + Boolean debug = (Boolean) headers.get(HEADER_DEBUG); Map voltageLevelsIdsRestricted; try { voltageLevelsIdsRestricted = headers.get(VOLTAGE_LEVELS_IDS_RESTRICTED) != null ? @@ -68,8 +68,7 @@ public static VoltageInitResultContext fromMessage(Message message, Obje String reporterId = headers.containsKey(REPORTER_ID_HEADER) ? (String) headers.get(REPORTER_ID_HEADER) : null; String reportType = headers.containsKey(REPORT_TYPE_HEADER) ? (String) headers.get(REPORT_TYPE_HEADER) : null; VoltageInitRunContext runContext = new VoltageInitRunContext( - networkUuid, variantId, receiver, reportUuid, reporterId, reportType, userId, parametersUuid, voltageLevelsIdsRestricted - ); + networkUuid, variantId, receiver, reportUuid, reporterId, reportType, userId, parametersUuid, voltageLevelsIdsRestricted, debug); return new VoltageInitResultContext(resultUuid, runContext); } diff --git a/src/main/java/org/gridsuite/voltageinit/server/service/VoltageInitResultService.java b/src/main/java/org/gridsuite/voltageinit/server/service/VoltageInitResultService.java index cd0ca68..19f3e27 100644 --- a/src/main/java/org/gridsuite/voltageinit/server/service/VoltageInitResultService.java +++ b/src/main/java/org/gridsuite/voltageinit/server/service/VoltageInitResultService.java @@ -7,6 +7,7 @@ package org.gridsuite.voltageinit.server.service; import com.powsybl.iidm.network.Bus; +import com.powsybl.openreac.parameters.output.OpenReacResult; import org.gridsuite.computation.service.AbstractComputationResultService; import org.gridsuite.voltageinit.server.dto.VoltageInitStatus; import org.gridsuite.voltageinit.server.entities.BusVoltageEmbeddable; @@ -19,14 +20,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import com.powsybl.openreac.parameters.output.OpenReacResult; - import java.time.Instant; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.UUID; +import java.util.*; import java.util.stream.Collectors; /** @@ -64,7 +59,7 @@ private static VoltageInitResultEntity toVoltageInitResultEntity(UUID resultUuid } ).filter(Objects::nonNull).toList(); return new VoltageInitResultEntity(resultUuid, Instant.now(), indicators, reactiveSlacks, busVoltages, modificationsGroupUuid, - isReactiveSlacksOverThreshold, reactiveSlacksThreshold); + isReactiveSlacksOverThreshold, reactiveSlacksThreshold, null); } @Override @@ -129,6 +124,25 @@ public void insert(UUID resultUuid, OpenReacResult result, Map netw @Transactional public void insertErrorResult(UUID resultUuid, Map errorIndicators) { Objects.requireNonNull(resultUuid); - resultRepository.save(new VoltageInitResultEntity(resultUuid, Instant.now(), errorIndicators, List.of(), List.of(), null, false, null)); + resultRepository.save(new VoltageInitResultEntity(resultUuid, Instant.now(), errorIndicators, List.of(), List.of(), null, false, null, null)); + } + + @Override + @Transactional + public void saveDebugFileLocation(UUID resultUuid, String debugFilePath) { + resultRepository.findById(resultUuid).ifPresentOrElse( + (var resultEntity) -> resultRepository.updateDebugFileLocation(resultUuid, debugFilePath), + () -> resultRepository.save(new VoltageInitResultEntity(resultUuid, null, null, null, null, null, + false, null, debugFilePath)) + ); + } + + @Override + @Transactional(readOnly = true) + public String findDebugFileLocation(UUID resultUuid) { + Objects.requireNonNull(resultUuid); + return resultRepository.findById(resultUuid) + .map(VoltageInitResultEntity::getDebugFileLocation) + .orElse(null); } } diff --git a/src/main/java/org/gridsuite/voltageinit/server/service/VoltageInitRunContext.java b/src/main/java/org/gridsuite/voltageinit/server/service/VoltageInitRunContext.java index e48902d..42f5330 100644 --- a/src/main/java/org/gridsuite/voltageinit/server/service/VoltageInitRunContext.java +++ b/src/main/java/org/gridsuite/voltageinit/server/service/VoltageInitRunContext.java @@ -24,15 +24,16 @@ public class VoltageInitRunContext extends AbstractComputationRunContext { private final Map voltageLevelsIdsRestricted; - public VoltageInitRunContext(UUID networkUuid, String variantId, String receiver, UUID reportUuid, String reporterId, String reportType, String userId, UUID parametersUuid, Map voltageLevelsIdsRestricted) { + public VoltageInitRunContext(UUID networkUuid, String variantId, String receiver, UUID reportUuid, String reporterId, + String reportType, String userId, UUID parametersUuid, Map voltageLevelsIdsRestricted, Boolean debug) { super(networkUuid, variantId, receiver, new ReportInfos(reportUuid, reporterId, reportType), userId, "default-provider", // TODO : replace with null when fix in powsybl-ws-commons will handle null provider - null); + null, debug); this.parametersUuid = parametersUuid; this.voltageLevelsIdsRestricted = voltageLevelsIdsRestricted; } - public VoltageInitRunContext(UUID networkUuid, String variantId, String receiver, UUID reportUuid, String reporterId, String reportType, String userId, UUID parametersUuid) { - this(networkUuid, variantId, receiver, reportUuid, reporterId, reportType, userId, parametersUuid, new HashMap<>()); + public VoltageInitRunContext(UUID networkUuid, String variantId, String receiver, UUID reportUuid, String reporterId, String reportType, String userId, UUID parametersUuid, Boolean debug) { + this(networkUuid, variantId, receiver, reportUuid, reporterId, reportType, userId, parametersUuid, new HashMap<>(), debug); } } diff --git a/src/main/java/org/gridsuite/voltageinit/server/service/VoltageInitService.java b/src/main/java/org/gridsuite/voltageinit/server/service/VoltageInitService.java index a4ff8bd..ede12ea 100644 --- a/src/main/java/org/gridsuite/voltageinit/server/service/VoltageInitService.java +++ b/src/main/java/org/gridsuite/voltageinit/server/service/VoltageInitService.java @@ -8,8 +8,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.powsybl.network.store.client.NetworkStoreService; - import org.gridsuite.computation.dto.GlobalFilter; +import org.gridsuite.computation.s3.ComputationS3Service; import org.gridsuite.computation.service.AbstractComputationService; import org.gridsuite.computation.service.NotificationService; import org.gridsuite.computation.service.UuidGeneratorService; @@ -45,9 +45,11 @@ public VoltageInitService(NotificationService notificationService, NetworkModificationService networkModificationService, UuidGeneratorService uuidGeneratorService, VoltageInitResultService resultService, + @Autowired(required = false) + ComputationS3Service computationS3Service, FilterService filterService, ObjectMapper objectMapper) { - super(notificationService, resultService, objectMapper, uuidGeneratorService, null); + super(notificationService, resultService, computationS3Service, objectMapper, uuidGeneratorService, null); this.networkModificationService = Objects.requireNonNull(networkModificationService); this.filterService = Objects.requireNonNull(filterService); } diff --git a/src/main/java/org/gridsuite/voltageinit/server/service/VoltageInitWorkerService.java b/src/main/java/org/gridsuite/voltageinit/server/service/VoltageInitWorkerService.java index 4376d64..7ea4bfb 100644 --- a/src/main/java/org/gridsuite/voltageinit/server/service/VoltageInitWorkerService.java +++ b/src/main/java/org/gridsuite/voltageinit/server/service/VoltageInitWorkerService.java @@ -18,12 +18,14 @@ import com.powsybl.openreac.parameters.input.OpenReacParameters; import com.powsybl.openreac.parameters.output.OpenReacResult; import com.powsybl.openreac.parameters.output.OpenReacStatus; +import org.gridsuite.computation.s3.ComputationS3Service; import org.gridsuite.computation.service.*; import org.gridsuite.voltageinit.server.dto.VoltageInitStatus; import org.gridsuite.voltageinit.server.dto.parameters.VoltageInitParametersInfos; import org.gridsuite.voltageinit.server.service.parameters.VoltageInitParametersService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.messaging.Message; import org.springframework.stereotype.Service; @@ -63,10 +65,12 @@ public VoltageInitWorkerService(NetworkStoreService networkStoreService, NetworkModificationService networkModificationService, VoltageInitParametersService voltageInitParametersService, VoltageInitResultService resultService, + @Autowired(required = false) + ComputationS3Service computationS3Service, ReportService reportService, VoltageInitObserver voltageInitObserver, ObjectMapper objectMapper) { - super(networkStoreService, notificationService, reportService, resultService, executionService, voltageInitObserver, objectMapper); + super(networkStoreService, notificationService, reportService, resultService, computationS3Service, executionService, voltageInitObserver, objectMapper); this.networkModificationService = Objects.requireNonNull(networkModificationService); this.voltageInitParametersService = Objects.requireNonNull(voltageInitParametersService); } @@ -88,6 +92,9 @@ private boolean checkReactiveSlacksOverThreshold(OpenReacResult openReacResult, @Override protected CompletableFuture getCompletableFuture(VoltageInitRunContext context, String provider, UUID resultUuid) { OpenReacParameters parameters = voltageInitParametersService.buildOpenReacParameters(context, context.getNetwork()); + if (context.getDebugDir() != null) { + parameters.setDebugDir(context.getDebugDir().toString()); + } OpenReacConfig config = OpenReacConfig.load(); return OpenReacRunner.runAsync(context.getNetwork(), context.getNetwork().getVariantManager().getWorkingVariantId(), parameters, config, executionService.getComputationManager(), context.getReportNode(), null); } diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index 6532747..aed7b95 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -4,6 +4,9 @@ server: spring: rabbitmq: addresses: localhost + cloud: + aws: + endpoint: http://localhost:19000 powsybl-ws: database: diff --git a/src/main/resources/config/application.yaml b/src/main/resources/config/application.yaml index e7788e2..e381098 100644 --- a/src/main/resources/config/application.yaml +++ b/src/main/resources/config/application.yaml @@ -15,6 +15,8 @@ spring: max-attempts: 1 publishRun-out-0: destination: ${powsybl-ws.rabbitmq.destination.prefix:}voltageinit.run + publishDebug-out-0: + destination: ${powsybl-ws.rabbitmq.destination.prefix:}voltageinit.debug publishResult-out-0: destination: ${powsybl-ws.rabbitmq.destination.prefix:}voltageinit.result consumeCancel-in-0: @@ -25,7 +27,7 @@ spring: destination: ${powsybl-ws.rabbitmq.destination.prefix:}voltageinit.stopped publishCancelFailed-out-0: destination: ${powsybl-ws.rabbitmq.destination.prefix:}voltageinit.cancelfailed - output-bindings: publishRun-out-0;publishResult-out-0;publishCancel-out-0;publishStopped-out-0;publishCancelFailed-out-0 + output-bindings: publishRun-out-0;publishDebug-out-0;publishResult-out-0;publishCancel-out-0;publishStopped-out-0;publishCancelFailed-out-0 rabbit: bindings: consumeRun-in-0: @@ -38,6 +40,12 @@ spring: enabled: true delivery-limit: 2 +computation: + s3: + enabled: true + +debug-subpath: debug + powsybl-ws: database: name: voltageinit diff --git a/src/main/resources/db/changelog/changesets/changelog_20250801T132858Z.xml b/src/main/resources/db/changelog/changesets/changelog_20250801T132858Z.xml new file mode 100644 index 0000000..4176ec7 --- /dev/null +++ b/src/main/resources/db/changelog/changesets/changelog_20250801T132858Z.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/src/main/resources/db/changelog/db.changelog-master.yaml b/src/main/resources/db/changelog/db.changelog-master.yaml index 8e927cb..6200afa 100644 --- a/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/src/main/resources/db/changelog/db.changelog-master.yaml @@ -42,3 +42,6 @@ databaseChangeLog: - include: file: changesets/changelog_20250711T130602Z.xml relativeToChangelogFile: true + - include: + file: changesets/changelog_20250801T132858Z.xml + relativeToChangelogFile: true diff --git a/src/test/java/org/gridsuite/voltageinit/server/VoltageInitControllerTest.java b/src/test/java/org/gridsuite/voltageinit/server/VoltageInitControllerTest.java index 511082f..f18275d 100644 --- a/src/test/java/org/gridsuite/voltageinit/server/VoltageInitControllerTest.java +++ b/src/test/java/org/gridsuite/voltageinit/server/VoltageInitControllerTest.java @@ -33,10 +33,6 @@ import com.powsybl.openreac.parameters.output.OpenReacResult; import com.powsybl.openreac.parameters.output.OpenReacStatus; import com.powsybl.openreac.parameters.output.ReactiveSlackOutput; -import org.gridsuite.computation.dto.GlobalFilter; -import org.gridsuite.computation.service.ReportService; -import org.gridsuite.computation.service.UuidGeneratorService; -import org.gridsuite.computation.utils.annotations.PostCompletionAdapter; import lombok.SneakyThrows; import mockwebserver3.Dispatcher; import mockwebserver3.MockResponse; @@ -45,6 +41,10 @@ import mockwebserver3.junit5.internal.MockWebServerExtension; import okhttp3.Headers; import okhttp3.HttpUrl; +import org.gridsuite.computation.dto.GlobalFilter; +import org.gridsuite.computation.service.ReportService; +import org.gridsuite.computation.service.UuidGeneratorService; +import org.gridsuite.computation.utils.annotations.PostCompletionAdapter; import org.gridsuite.filter.identifierlistfilter.IdentifierListFilter; import org.gridsuite.filter.identifierlistfilter.IdentifierListFilterEquipmentAttributes; import org.gridsuite.filter.utils.EquipmentType; @@ -70,6 +70,7 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.cloud.stream.binder.test.OutputDestination; import org.springframework.cloud.stream.binder.test.TestChannelBinderConfiguration; import org.springframework.http.HttpHeaders; @@ -80,24 +81,30 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.transaction.support.TransactionSynchronizationManager; - +import software.amazon.awssdk.core.ResponseInputStream; +import software.amazon.awssdk.core.sync.RequestBody; +import software.amazon.awssdk.http.AbortableInputStream; +import software.amazon.awssdk.services.s3.S3Client; +import software.amazon.awssdk.services.s3.model.GetObjectRequest; +import software.amazon.awssdk.services.s3.model.GetObjectResponse; +import software.amazon.awssdk.services.s3.model.PutObjectRequest; +import software.amazon.awssdk.services.s3.model.PutObjectResponse; + +import java.io.ByteArrayInputStream; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.UUID; +import java.util.*; import java.util.concurrent.ForkJoinPool; import static com.powsybl.network.store.model.NetworkStoreApi.VERSION; +import static org.assertj.core.api.Assertions.assertThat; +import static org.gridsuite.computation.s3.ComputationS3Service.METADATA_FILE_NAME; import static org.gridsuite.computation.service.NotificationService.*; import static org.gridsuite.voltageinit.server.service.VoltageInitWorkerService.*; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -156,6 +163,9 @@ class VoltageInitControllerTest { @Autowired private ObjectMapper mapper; + @SpyBean + private S3Client s3Client; + private Network network; private OpenReacParameters openReacParameters; private OpenReacResult openReacResult; @@ -316,6 +326,8 @@ public MockResponse dispatch(RecordedRequest request) { server.setDispatcher(dispatcher); // purge messages + while (output.receive(1000, "voltageinit.debug") != null) { + } while (output.receive(1000, "voltageinit.result") != null) { } // purge messages @@ -344,8 +356,18 @@ void runTest() throws Exception { openReacRunnerMockedStatic.when(() -> OpenReacRunner.runAsync(eq(network), eq(VARIANT_2_ID), any(OpenReacParameters.class), any(OpenReacConfig.class), any(ComputationManager.class), any(ReportNode.class), isNull(AmplExportConfig.class))) .thenReturn(completableFutureResultsTask); + // mock s3 client for run with debug + doReturn(PutObjectResponse.builder().build()).when(s3Client).putObject(eq(PutObjectRequest.builder().build()), any(RequestBody.class)); + doReturn(new ResponseInputStream<>( + GetObjectResponse.builder() + .metadata(Map.of(METADATA_FILE_NAME, "debugFile")) + .contentLength(100L).build(), + AbortableInputStream.create(new ByteArrayInputStream("s3 debug file content".getBytes())) + )).when(s3Client).getObject(any(GetObjectRequest.class)); + MvcResult result = mockMvc.perform(post( "/" + VERSION + "/networks/{networkUuid}/run-and-save?receiver=me&variantId=" + VARIANT_2_ID, NETWORK_UUID) + .param(HEADER_DEBUG, "true") .header(HEADER_USER_ID, "userId")) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) @@ -353,9 +375,24 @@ void runTest() throws Exception { assertEquals(RESULT_UUID, mapper.readValue(result.getResponse().getContentAsString(), UUID.class)); Message resultMessage = output.receive(TIMEOUT, "voltageinit.result"); - assertEquals(RESULT_UUID.toString(), resultMessage.getHeaders().get("resultUuid")); + String resultUuid = Objects.requireNonNull(resultMessage.getHeaders().get("resultUuid")).toString(); + + assertEquals(RESULT_UUID.toString(), resultUuid); assertEquals("me", resultMessage.getHeaders().get("receiver")); + // check notification of debug + Message debugMessage = output.receive(TIMEOUT, "voltageinit.debug"); + assertThat(debugMessage.getHeaders()) + .containsEntry(HEADER_RESULT_UUID, resultUuid); + + // download debug zip file is ok + mockMvc.perform(get("/v1/results/{resultUuid}/download-debug-file", resultUuid)) + .andExpect(status().isOk()); + + // check interaction with s3 client + verify(s3Client, times(1)).putObject(any(PutObjectRequest.class), any(RequestBody.class)); + verify(s3Client, times(1)).getObject(any(GetObjectRequest.class)); + // get result result = mockMvc.perform(get( "/" + VERSION + "/results/{resultUuid}", RESULT_UUID)) diff --git a/src/test/java/org/gridsuite/voltageinit/server/service/parameters/ParametersTest.java b/src/test/java/org/gridsuite/voltageinit/server/service/parameters/ParametersTest.java index e8467c9..830ee18 100644 --- a/src/test/java/org/gridsuite/voltageinit/server/service/parameters/ParametersTest.java +++ b/src/test/java/org/gridsuite/voltageinit/server/service/parameters/ParametersTest.java @@ -148,7 +148,7 @@ private ListAssert testsBuildSpecificVoltageLimitsCommon(L final VoltageInitParametersEntity voltageInitParameters = entityManager.persistFlushFind( new VoltageInitParametersEntity(null, null, "", voltageLimits, null, EquipmentsSelectionType.ALL_EXCEPT, null, EquipmentsSelectionType.NONE_EXCEPT, null, EquipmentsSelectionType.NONE_EXCEPT, 100., 0., false) ); - final VoltageInitRunContext context = new VoltageInitRunContext(NETWORK_UUID, VARIANT_ID_1, null, REPORT_UUID, null, "", "", voltageInitParameters.getId()); + final VoltageInitRunContext context = new VoltageInitRunContext(NETWORK_UUID, VARIANT_ID_1, null, REPORT_UUID, null, "", "", voltageInitParameters.getId(), false); context.setReportNode(ReportNode.newRootReportNode() .withResourceBundles("i18n.reports") .withMessageTemplate(COMPUTATION_TYPE).build()); @@ -261,7 +261,7 @@ void testsBuildSpecificVoltageLimitsWithFourSubstationStudy() throws Exception { new VoltageInitParametersEntity(null, null, "", List.of(vl1, vl2, vl3, vl4), null, EquipmentsSelectionType.ALL_EXCEPT, null, EquipmentsSelectionType.NONE_EXCEPT, null, EquipmentsSelectionType.NONE_EXCEPT, 100., 0., false) ); - final VoltageInitRunContext context = new VoltageInitRunContext(networkUuid, variantId, null, REPORT_UUID, null, "", "", voltageInitParameters.getId()); + final VoltageInitRunContext context = new VoltageInitRunContext(networkUuid, variantId, null, REPORT_UUID, null, "", "", voltageInitParameters.getId(), false); context.setReportNode(ReportNode.newRootReportNode() .withResourceBundles("i18n.reports") .withMessageTemplate("VoltageInit").build());