diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/controllers/MonitorController.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/controllers/MonitorController.java index d450879..65ec8bc 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/controllers/MonitorController.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/controllers/MonitorController.java @@ -82,4 +82,15 @@ public ResponseEntity> getStepsInfos(@Parameter(descr return monitorService.getStepsInfos(executionId).map(list -> ResponseEntity.ok().body(list)) .orElseGet(() -> ResponseEntity.notFound().build()); } + + @DeleteMapping("/executions/{executionId}") + @Operation(summary = "Delete an execution") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Execution was deleted"), + @ApiResponse(responseCode = "404", description = "Execution was not found")}) + public ResponseEntity deleteExecution(@PathVariable UUID executionId) { + return monitorService.deleteExecution(executionId) ? + ResponseEntity.ok().build() : + ResponseEntity.notFound().build(); + } } + diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/entities/ProcessExecutionEntity.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/entities/ProcessExecutionEntity.java index 0f1a3dd..eaaeaa1 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/entities/ProcessExecutionEntity.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/entities/ProcessExecutionEntity.java @@ -23,7 +23,7 @@ @NoArgsConstructor @AllArgsConstructor @Builder -@Table(name = "processExecution") +@Table(name = "process_execution") public class ProcessExecutionEntity { @Id diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/entities/ProcessExecutionStepEntity.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/entities/ProcessExecutionStepEntity.java index 0a3e2b6..a2b0a95 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/entities/ProcessExecutionStepEntity.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/entities/ProcessExecutionStepEntity.java @@ -23,7 +23,7 @@ @NoArgsConstructor @AllArgsConstructor @Builder -@Table(name = "processExecutionStep") +@Table(name = "process_execution_step") public class ProcessExecutionStepEntity { @Id diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/MonitorService.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/MonitorService.java index 45ac6d4..d0722e5 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/MonitorService.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/MonitorService.java @@ -6,7 +6,6 @@ */ package org.gridsuite.monitor.server.services; -import lombok.RequiredArgsConstructor; import org.gridsuite.monitor.commons.ProcessConfig; import org.gridsuite.monitor.commons.ProcessExecutionStep; import org.gridsuite.monitor.commons.ProcessStatus; @@ -23,6 +22,7 @@ import org.springframework.transaction.annotation.Transactional; import java.time.Instant; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -31,7 +31,6 @@ * @author Antoine Bouhours */ @Service -@RequiredArgsConstructor public class MonitorService { private final ProcessExecutionRepository executionRepository; @@ -39,6 +38,16 @@ public class MonitorService { private final ReportService reportService; private final ResultService resultService; + public MonitorService(ProcessExecutionRepository executionRepository, + NotificationService notificationService, + ReportService reportService, + ResultService resultService) { + this.executionRepository = executionRepository; + this.notificationService = notificationService; + this.reportService = reportService; + this.resultService = resultService; + } + @Transactional public UUID executeProcess(UUID caseUuid, String userId, ProcessConfig processConfig) { ProcessExecutionEntity execution = ProcessExecutionEntity.builder() @@ -180,4 +189,29 @@ public Optional> getStepsInfos(UUID executionId) { return Optional.empty(); } } + + @Transactional + public boolean deleteExecution(UUID executionId) { + List resultIds = new ArrayList<>(); + List reportIds = new ArrayList<>(); + + Optional executionEntity = executionRepository.findById(executionId); + if (executionEntity.isPresent()) { + Optional.ofNullable(executionEntity.get().getSteps()).orElse(List.of()).forEach(step -> { + if (step.getResultId() != null && step.getResultType() != null) { + resultIds.add(new ResultInfos(step.getResultId(), step.getResultType())); + } + if (step.getReportId() != null) { + reportIds.add(step.getReportId()); + } + }); + resultIds.forEach(resultService::deleteResult); + reportIds.forEach(reportService::deleteReport); + + executionRepository.deleteById(executionId); + + return true; + } + return false; + } } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/ReportService.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/ReportService.java index cdf59e0..21f5575 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/ReportService.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/ReportService.java @@ -52,4 +52,12 @@ public ReportPage getReport(UUID reportId) { return restTemplate.exchange(this.getReportServerURI() + path, HttpMethod.GET, new HttpEntity<>(headers), new ParameterizedTypeReference() { }).getBody(); } + + public void deleteReport(UUID reportId) { + var path = UriComponentsBuilder.fromPath("{id}") + .buildAndExpand(reportId) + .toUriString(); + + restTemplate.delete(this.getReportServerURI() + path); + } } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/ResultProvider.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/ResultProvider.java index d80f407..e66f2d0 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/ResultProvider.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/ResultProvider.java @@ -17,4 +17,6 @@ public interface ResultProvider { ResultType getType(); String getResult(UUID resultId); + + void deleteResult(UUID resultId); } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/ResultService.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/ResultService.java index 04101ea..3e1bd22 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/ResultService.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/ResultService.java @@ -31,12 +31,19 @@ public ResultService(List resultProviders) { )); } - public String getResult(ResultInfos resultInfos) { - ResultProvider provider = providers.get(resultInfos.resultType()); - if (provider != null) { - return provider.getResult(resultInfos.resultUUID()); - } else { - throw new IllegalArgumentException("Unsupported result type: " + resultInfos.resultType()); + public ResultProvider getProvider(ResultType resultType) { + ResultProvider provider = providers.get(resultType); + if (provider == null) { + throw new IllegalArgumentException("Unsupported result type: " + resultType); } + return provider; + } + + public String getResult(ResultInfos resultInfos) { + return getProvider(resultInfos.resultType()).getResult(resultInfos.resultUUID()); + } + + public void deleteResult(ResultInfos resultInfos) { + getProvider(resultInfos.resultType()).deleteResult(resultInfos.resultUUID()); } } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/SecurityAnalysisResultProvider.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/SecurityAnalysisResultProvider.java index 9b99f2d..b446d1d 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/SecurityAnalysisResultProvider.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/SecurityAnalysisResultProvider.java @@ -31,4 +31,9 @@ public ResultType getType() { public String getResult(UUID resultId) { return securityAnalysisService.getResult(resultId); } + + @Override + public void deleteResult(UUID resultId) { + securityAnalysisService.deleteResult(resultId); + } } diff --git a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/SecurityAnalysisService.java b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/SecurityAnalysisService.java index 3779d74..0af66bf 100644 --- a/monitor-server/src/main/java/org/gridsuite/monitor/server/services/SecurityAnalysisService.java +++ b/monitor-server/src/main/java/org/gridsuite/monitor/server/services/SecurityAnalysisService.java @@ -16,6 +16,7 @@ import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; +import java.util.List; import java.util.UUID; /** @@ -52,4 +53,15 @@ public String getResult(UUID resultUuid) { return restTemplate.exchange(getSecurityAnalysisServerBaseUri() + path, HttpMethod.GET, null, String.class).getBody(); } + + public void deleteResult(UUID resultUuid) { + LOGGER.info("Deleting result {}", resultUuid); + + var path = UriComponentsBuilder.fromPath("/results") + .queryParam("resultsUuids", List.of(resultUuid)) + .build() + .toUriString(); + + restTemplate.delete(getSecurityAnalysisServerBaseUri() + path); + } } diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/MonitorControllerTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/MonitorControllerTest.java index 66adb07..18c6a10 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/MonitorControllerTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/controllers/MonitorControllerTest.java @@ -34,6 +34,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @@ -183,4 +184,28 @@ void getStepsInfosShouldReturn404WhenExecutionNotFound() throws Exception { verify(monitorService).getStepsInfos(executionId); } + + @Test + void deleteExecutionShouldReturnTrue() throws Exception { + UUID executionId = UUID.randomUUID(); + when(monitorService.deleteExecution(executionId)) + .thenReturn(Boolean.TRUE); + + mockMvc.perform(delete("/v1/executions/{executionId}", executionId)) + .andExpect(status().isOk()); + + verify(monitorService).deleteExecution(executionId); + } + + @Test + void deleteExecutionShouldReturnFalse() throws Exception { + UUID executionId = UUID.randomUUID(); + when(monitorService.deleteExecution(executionId)) + .thenReturn(Boolean.FALSE); + + mockMvc.perform(delete("/v1/executions/{executionId}", executionId)) + .andExpect(status().isNotFound()); + + verify(monitorService).deleteExecution(executionId); + } } diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/MonitorServiceTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/MonitorServiceTest.java index 0fa31f1..fd1c712 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/MonitorServiceTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/MonitorServiceTest.java @@ -497,4 +497,58 @@ void getStepsInfosShouldReturnEmptyListWhenNoSteps() { assertThat(result).isPresent(); assertThat(result.get()).isEmpty(); } + + @Test + void deleteExecutionShouldDeleteResultsAndReports() { + UUID reportId1 = UUID.randomUUID(); + UUID resultId1 = UUID.randomUUID(); + UUID reportId2 = UUID.randomUUID(); + UUID resultId2 = UUID.randomUUID(); + ProcessExecutionStepEntity step0 = ProcessExecutionStepEntity.builder() + .id(UUID.randomUUID()) + .stepOrder(0) + .reportId(reportId1) + .resultId(resultId1) + .build(); + ProcessExecutionStepEntity step1 = ProcessExecutionStepEntity.builder() + .id(UUID.randomUUID()) + .stepOrder(1) + .reportId(reportId2) + .resultId(resultId2) + .resultType(ResultType.SECURITY_ANALYSIS) + .build(); + ProcessExecutionEntity execution = ProcessExecutionEntity.builder() + .id(executionId) + .steps(List.of(step0, step1)) + .build(); + + when(executionRepository.findById(executionId)).thenReturn(Optional.of(execution)); + doNothing().when(executionRepository).deleteById(executionId); + + doNothing().when(reportService).deleteReport(reportId1); + doNothing().when(reportService).deleteReport(reportId2); + doNothing().when(resultService).deleteResult(any(ResultInfos.class)); + + boolean done = monitorService.deleteExecution(executionId); + assertThat(done).isTrue(); + + verify(executionRepository).findById(executionId); + verify(executionRepository).deleteById(executionId); + verify(reportService).deleteReport(reportId1); + verify(reportService).deleteReport(reportId2); + verify(resultService, times(1)).deleteResult(any(ResultInfos.class)); + } + + @Test + void deleteExecutionShouldReturnFalseWhenExecutionNotFound() { + when(executionRepository.findById(executionId)).thenReturn(Optional.empty()); + + boolean done = monitorService.deleteExecution(executionId); + assertThat(done).isFalse(); + + verify(executionRepository).findById(executionId); + verifyNoInteractions(reportService); + verifyNoInteractions(resultService); + verify(executionRepository, never()).deleteById(executionId); + } } diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/ReportServiceTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/ReportServiceTest.java index 57c9153..dde1ca9 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/ReportServiceTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/ReportServiceTest.java @@ -26,6 +26,7 @@ import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatNoException; import static org.assertj.core.api.Assertions.assertThatThrownBy; /** @@ -71,4 +72,26 @@ void getReportFailed() { assertThatThrownBy(() -> reportService.getReport(reportId)).isInstanceOf(RestClientException.class); } + + @Test + void deleteReport() { + UUID reportId = UUID.randomUUID(); + + server.expect(MockRestRequestMatchers.method(HttpMethod.DELETE)) + .andExpect(MockRestRequestMatchers.requestTo("http://report-server/v1/reports/" + reportId)) + .andRespond(MockRestResponseCreators.withSuccess()); + + assertThatNoException().isThrownBy(() -> reportService.deleteReport(reportId)); + } + + @Test + void deleteReportFailed() { + UUID reportId = UUID.randomUUID(); + + server.expect(MockRestRequestMatchers.method(HttpMethod.DELETE)) + .andExpect(MockRestRequestMatchers.requestTo("http://report-server/v1/reports/" + reportId)) + .andRespond(MockRestResponseCreators.withServerError()); + + assertThatThrownBy(() -> reportService.deleteReport(reportId)).isInstanceOf(RestClientException.class); + } } diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/ResultServiceTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/ResultServiceTest.java index acfdc4b..4c617c5 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/ResultServiceTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/ResultServiceTest.java @@ -18,6 +18,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -58,4 +59,29 @@ void getResultShouldThrowExceptionWhenProviderNotFound() { .isInstanceOf(IllegalArgumentException.class) .hasMessageContaining("Unsupported result type: " + ResultType.SECURITY_ANALYSIS); } + + @Test + void deleteResultShouldDeleteFromCorrectProvider() { + UUID resultId = UUID.randomUUID(); + doNothing().when(resultProvider).deleteResult(resultId); + when(resultProvider.getType()).thenReturn(ResultType.SECURITY_ANALYSIS); + resultService = new ResultService(List.of(resultProvider)); + ResultInfos resultInfos = new ResultInfos(resultId, ResultType.SECURITY_ANALYSIS); + + resultService.deleteResult(resultInfos); + + verify(resultProvider).deleteResult(resultId); + } + + @Test + void deleteResultShouldThrowExceptionWhenProviderNotFound() { + UUID resultId = UUID.randomUUID(); + ResultInfos resultInfos = new ResultInfos(resultId, ResultType.SECURITY_ANALYSIS); + + ResultService emptyService = new ResultService(List.of()); + + assertThatThrownBy(() -> emptyService.deleteResult(resultInfos)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("Unsupported result type: " + ResultType.SECURITY_ANALYSIS); + } } diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/SecurityAnalysisResultProviderTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/SecurityAnalysisResultProviderTest.java index 29d5780..f02ba95 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/SecurityAnalysisResultProviderTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/SecurityAnalysisResultProviderTest.java @@ -44,4 +44,16 @@ void getResultShouldDelegateToSecurityAnalysisService() { verify(securityAnalysisService).getResult(id); verifyNoMoreInteractions(securityAnalysisService); } + + @Test + void deleteResultShouldDelegateToSecurityAnalysisService() { + UUID id = UUID.randomUUID(); + + doNothing().when(securityAnalysisService).deleteResult(id); + + provider.deleteResult(id); + + verify(securityAnalysisService).deleteResult(id); + verifyNoMoreInteractions(securityAnalysisService); + } } diff --git a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/SecurityAnalysisServiceTest.java b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/SecurityAnalysisServiceTest.java index a236e6d..bf8b690 100644 --- a/monitor-server/src/test/java/org/gridsuite/monitor/server/services/SecurityAnalysisServiceTest.java +++ b/monitor-server/src/test/java/org/gridsuite/monitor/server/services/SecurityAnalysisServiceTest.java @@ -20,6 +20,7 @@ import java.util.UUID; +import static org.assertj.core.api.Assertions.assertThatNoException; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; @@ -71,4 +72,23 @@ void getResultFailed() { assertThatThrownBy(() -> securityAnalysisService.getResult(RESULT_UUID)) .isInstanceOf(RestClientException.class); } + + @Test + void deleteResult() { + server.expect(MockRestRequestMatchers.method(HttpMethod.DELETE)) + .andExpect(MockRestRequestMatchers.requestTo("http://security-analysis-server/v1/results?resultsUuids=" + RESULT_UUID)) + .andRespond(MockRestResponseCreators.withSuccess()); + + assertThatNoException().isThrownBy(() -> securityAnalysisService.deleteResult(RESULT_UUID)); + } + + @Test + void deleteResultFailed() { + server.expect(MockRestRequestMatchers.method(HttpMethod.DELETE)) + .andExpect(MockRestRequestMatchers.requestTo("http://security-analysis-server/v1/results?resultsUuids=" + RESULT_UUID)) + .andRespond(MockRestResponseCreators.withServerError()); + + assertThatThrownBy(() -> securityAnalysisService.deleteResult(RESULT_UUID)) + .isInstanceOf(RestClientException.class); + } }