diff --git a/Backend/src/main/java/unical/demacs/rdm/controller/JsonController.java b/Backend/src/main/java/unical/demacs/rdm/controller/JsonController.java index 7862d41..7b0783a 100644 --- a/Backend/src/main/java/unical/demacs/rdm/controller/JsonController.java +++ b/Backend/src/main/java/unical/demacs/rdm/controller/JsonController.java @@ -3,14 +3,12 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.AllArgsConstructor; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; +import org.springframework.http.*; import org.springframework.web.bind.annotation.*; import unical.demacs.rdm.config.ModelMapperExtended; import unical.demacs.rdm.persistence.dto.JobDTO; import unical.demacs.rdm.persistence.dto.MachineDTO; import unical.demacs.rdm.persistence.dto.MachineTypeDTO; -import unical.demacs.rdm.persistence.dto.ScheduleDTO; import unical.demacs.rdm.persistence.dto.ScheduleWithMachineDTO; import unical.demacs.rdm.persistence.entities.Job; import unical.demacs.rdm.persistence.entities.Machine; @@ -138,4 +136,19 @@ public ResponseEntity> exportJobScheduledRO() { List schedules = jsonService.readScheduleFile("./data/job-scheduled-ro.json"); return ResponseEntity.ok(schedules); } + + @Operation(summary = "Download all Schedules as JSON", description = "Download all Schedules as a JSON file.", + tags = {"json-controller"}) + @GetMapping(value = "/download-schedules", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity downloadSchedules() { + try { + byte[] jsonContent = jsonService.exportSchedulesToJson(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentDisposition(ContentDisposition.builder("attachment").filename("schedules.json").build()); + headers.setContentType(MediaType.APPLICATION_JSON); + return new ResponseEntity<>(jsonContent, headers, HttpStatus.OK); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error exporting schedules: ".getBytes()); + } + } } \ No newline at end of file diff --git a/Backend/src/main/java/unical/demacs/rdm/persistence/service/implementation/JsonServiceImpl.java b/Backend/src/main/java/unical/demacs/rdm/persistence/service/implementation/JsonServiceImpl.java index 1d4fe9f..895f309 100644 --- a/Backend/src/main/java/unical/demacs/rdm/persistence/service/implementation/JsonServiceImpl.java +++ b/Backend/src/main/java/unical/demacs/rdm/persistence/service/implementation/JsonServiceImpl.java @@ -4,17 +4,21 @@ import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import unical.demacs.rdm.persistence.dto.*; +import unical.demacs.rdm.persistence.entities.Schedule; +import unical.demacs.rdm.persistence.repository.ScheduleRepository; import unical.demacs.rdm.persistence.service.interfaces.IJsonService; import java.io.File; import java.io.IOException; import java.util.List; +import java.util.stream.Collectors; @Service @AllArgsConstructor public class JsonServiceImpl implements IJsonService { private final ObjectMapper objectMapper; + private final ScheduleRepository scheduleRepository; public List readScheduleFile(String fileName) { File file = new File(fileName); @@ -25,4 +29,31 @@ public List readScheduleFile(String fileName) { throw new RuntimeException(e); } } + + public List getAllSchedules() { + List schedules = scheduleRepository.findAll(); + return schedules.stream() + .map(schedule -> new ScheduleDTO( + schedule.getId(), + schedule.getJob().getId(), + schedule.getMachineType().getId(), + schedule.getDueDate(), + schedule.getStartTime(), + schedule.getDuration(), + schedule.getStatus(), + schedule.getMachine() != null ? schedule.getMachine().getId() : null, + schedule.getMachine() != null ? schedule.getMachine().getName() : null + )) + .collect(Collectors.toList()); + } + + public byte[] exportSchedulesToJson() { + try { + List schedules = getAllSchedules(); + return objectMapper.writeValueAsBytes(schedules); + } catch (IOException e) { + throw new RuntimeException("Errore durante l'esportazione degli schedule in JSON", e); + } + } + } \ No newline at end of file diff --git a/Backend/src/main/java/unical/demacs/rdm/persistence/service/interfaces/IJsonService.java b/Backend/src/main/java/unical/demacs/rdm/persistence/service/interfaces/IJsonService.java index 40dae6c..3e46ba2 100644 --- a/Backend/src/main/java/unical/demacs/rdm/persistence/service/interfaces/IJsonService.java +++ b/Backend/src/main/java/unical/demacs/rdm/persistence/service/interfaces/IJsonService.java @@ -1,9 +1,12 @@ package unical.demacs.rdm.persistence.service.interfaces; +import unical.demacs.rdm.persistence.dto.ScheduleDTO; import unical.demacs.rdm.persistence.dto.ScheduleWithMachineDTO; import java.util.List; public interface IJsonService { public List readScheduleFile(String fileName); + public List getAllSchedules(); + public byte[] exportSchedulesToJson(); } \ No newline at end of file diff --git a/Backend/src/test/java/unical/demacs/rdm/service/JsonServiceImplTest.java b/Backend/src/test/java/unical/demacs/rdm/service/JsonServiceImplTest.java index 8223073..2594c99 100644 --- a/Backend/src/test/java/unical/demacs/rdm/service/JsonServiceImplTest.java +++ b/Backend/src/test/java/unical/demacs/rdm/service/JsonServiceImplTest.java @@ -9,6 +9,7 @@ import unical.demacs.rdm.persistence.dto.ScheduleDTO; import unical.demacs.rdm.persistence.dto.ScheduleWithMachineDTO; import unical.demacs.rdm.persistence.enums.ScheduleStatus; +import unical.demacs.rdm.persistence.repository.ScheduleRepository; import unical.demacs.rdm.persistence.service.implementation.JsonServiceImpl; import unical.demacs.rdm.persistence.service.interfaces.IJsonService; @@ -28,10 +29,13 @@ public class JsonServiceImplTest { @Mock private IJsonService jsonService; + @Mock + private ScheduleRepository scheduleRepository; + @BeforeEach void setUp() { objectMapper = new ObjectMapper(); - jsonService = new JsonServiceImpl(objectMapper); + jsonService = new JsonServiceImpl(objectMapper, scheduleRepository); } @Test diff --git a/Frontend/src/app/components/schedule/schedule.component.html b/Frontend/src/app/components/schedule/schedule.component.html index e963966..a3bc136 100644 --- a/Frontend/src/app/components/schedule/schedule.component.html +++ b/Frontend/src/app/components/schedule/schedule.component.html @@ -54,6 +54,7 @@

Tutti i Job

Job partecipanti alla schedulazione

+
diff --git a/Frontend/src/app/components/schedule/schedule.component.ts b/Frontend/src/app/components/schedule/schedule.component.ts index 0ed3ef7..4000bf1 100644 --- a/Frontend/src/app/components/schedule/schedule.component.ts +++ b/Frontend/src/app/components/schedule/schedule.component.ts @@ -10,6 +10,7 @@ import { ScheduleControllerService, JobControllerService, SchedulerEngineService, + JsonControllerService, } from '../../generated-api'; import { MatDialog, MatDialogRef } from '@angular/material/dialog'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; @@ -51,6 +52,7 @@ export class ScheduleComponent implements OnInit { constructor( private jobService: JobControllerService, private scheduleService: ScheduleControllerService, + private jsonService: JsonControllerService, private dialog: MatDialog, private fb: FormBuilder, private schedulerEngineService: SchedulerEngineService @@ -427,4 +429,15 @@ export class ScheduleComponent implements OnInit { } protected readonly Number = Number; + + downloadSchedules() { + this.jsonService.downloadSchedules().subscribe(response => { + const blob = new Blob([response], { type: 'application/json' }); + const link = document.createElement('a'); + link.href = URL.createObjectURL(blob); + link.download = 'schedules.json'; + link.click(); + }); + } + } diff --git a/Frontend/src/app/generated-api/api/jsonController.service.ts b/Frontend/src/app/generated-api/api/jsonController.service.ts index 8f406c1..7a0ee2e 100644 --- a/Frontend/src/app/generated-api/api/jsonController.service.ts +++ b/Frontend/src/app/generated-api/api/jsonController.service.ts @@ -94,6 +94,36 @@ export class JsonControllerService { ); } + /** + * Download schedules as a JSON file + * This method triggers the download of the schedules JSON file. + * @param observe set whether or not to return the data Observable as the body, response or events. + * @param reportProgress flag to report request and response progress. + */ + public downloadSchedules(observe?: 'body', reportProgress?: boolean): Observable; + public downloadSchedules(observe?: 'response', reportProgress?: boolean): Observable>; + public downloadSchedules(observe?: 'events', reportProgress?: boolean): Observable>; + public downloadSchedules(observe: any = 'body', reportProgress: boolean = false ): Observable { + + let headers = this.defaultHeaders; + + let httpHeaderAccepts: string[] = [ + 'application/json' + ]; + const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts); + if (httpHeaderAcceptSelected != undefined) { + headers = headers.set('Accept', httpHeaderAcceptSelected); + } + + return this.httpClient.request('get', `${this.basePath}/api/v1/json/download-schedules`, { + withCredentials: this.configuration.withCredentials, + headers: headers, + observe: observe, + responseType: 'blob', + reportProgress: reportProgress + }); + } + /** * Export Job data to JSON * Export all Job data to JSON.