diff --git a/api/src/main/java/ca/bc/gov/educ/api/gradbusiness/exception/ServiceException.java b/api/src/main/java/ca/bc/gov/educ/api/gradbusiness/exception/ServiceException.java new file mode 100644 index 0000000..29f3f31 --- /dev/null +++ b/api/src/main/java/ca/bc/gov/educ/api/gradbusiness/exception/ServiceException.java @@ -0,0 +1,15 @@ +package ca.bc.gov.educ.api.gradbusiness.exception; + +import lombok.Data; + +@Data +public class ServiceException extends RuntimeException { + + private final int statusCode; + + public ServiceException(String message, int value) { + super(message); + this.statusCode = value; + } + +} diff --git a/api/src/main/java/ca/bc/gov/educ/api/gradbusiness/service/GradBusinessService.java b/api/src/main/java/ca/bc/gov/educ/api/gradbusiness/service/GradBusinessService.java index d208502..3e71b16 100644 --- a/api/src/main/java/ca/bc/gov/educ/api/gradbusiness/service/GradBusinessService.java +++ b/api/src/main/java/ca/bc/gov/educ/api/gradbusiness/service/GradBusinessService.java @@ -1,5 +1,6 @@ package ca.bc.gov.educ.api.gradbusiness.service; +import ca.bc.gov.educ.api.gradbusiness.exception.ServiceException; import ca.bc.gov.educ.api.gradbusiness.model.dto.Student; import ca.bc.gov.educ.api.gradbusiness.util.EducGradBusinessApiConstants; import ca.bc.gov.educ.api.gradbusiness.util.EducGradBusinessUtil; @@ -22,10 +23,10 @@ import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.reactive.function.client.WebClient; -import java.io.FileOutputStream; +import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; +import java.nio.file.Files; import java.util.*; import java.util.concurrent.CompletableFuture; @@ -41,7 +42,7 @@ public class GradBusinessService { private static final String APPLICATION_JSON = "application/json"; private static final String APPLICATION_PDF = "application/pdf"; private static final String ACCEPT = "*/*"; - private static final String TMP = "/tmp"; + private static final String TMP = File.separator + "tmp"; /** * The Web client. */ @@ -272,9 +273,17 @@ public ResponseEntity getStudentTranscriptPDFByType(String pen, String t headers.put(HttpHeaders.AUTHORIZATION, Collections.singletonList(BEARER + accessToken)); headers.put(HttpHeaders.ACCEPT, Collections.singletonList(ACCEPT)); headers.put(HttpHeaders.CONTENT_TYPE, Collections.singletonList(APPLICATION_JSON)); - byte[] result = webClient.post().uri(educGraduationApiConstants.getStudentTranscriptReportByRequest()).headers(h -> h.addAll(headers)).body(BodyInserters.fromValue(reportRequest.toString())).retrieve().bodyToMono(byte[].class).block(); + byte[] result = webClient.post().uri(educGraduationApiConstants.getStudentTranscriptReportByRequest()) + .headers(h -> h.addAll(headers)).body(BodyInserters.fromValue(reportRequest.toString())).retrieve() + .onStatus( + HttpStatus.NO_CONTENT::equals, + response -> response.bodyToMono(String.class).thenReturn(new ServiceException("NO_CONTENT", response.statusCode().value())) + ) + .bodyToMono(byte[].class).block(); assert result != null; return handleBinaryResponse(result, pen + " Transcript Report.pdf", MediaType.APPLICATION_PDF); + } catch (ServiceException e) { + return handleBinaryResponse(new byte[0], pen + " Transcript Report.pdf", MediaType.APPLICATION_PDF); } catch (Exception e) { return getInternalServerErrorResponse(e); } @@ -337,8 +346,9 @@ protected ResponseEntity getInternalServerErrorResponse(Throwable t) { private ResponseEntity handleBinaryResponse(byte[] resultBinary, String reportFile, MediaType contentType) { ResponseEntity response; - if(resultBinary.length > 0) { + String fileType = contentType.getSubtype().toUpperCase(); + logger.debug("Sending {} response {} KB", fileType, resultBinary.length/(1024)); HttpHeaders headers = new HttpHeaders(); headers.add("Content-Disposition", "inline; filename=" + reportFile); response = ResponseEntity @@ -354,9 +364,15 @@ private ResponseEntity handleBinaryResponse(byte[] resultBinary, String private void saveBinaryResponseToFile(byte[] resultBinary, String reportFile) throws IOException { if(resultBinary.length > 0) { - try (OutputStream out = new FileOutputStream(TMP + "/" + reportFile)) { - out.write(resultBinary); + String pathToFile = TMP + File.separator + reportFile; + logger.debug("Save generated PDF {} on the file system", reportFile); + File fileToSave = new File(pathToFile); + if(fileToSave.exists()) { + boolean isDeleted = fileToSave.delete(); + logger.debug("{} to delete existing PDF {}", isDeleted, reportFile); } + Files.write(fileToSave.toPath(), resultBinary); + logger.debug("PDF {} saved successfully", pathToFile); } } } diff --git a/api/src/test/java/ca/bc/gov/educ/api/gradbusiness/EducGradBusinessApiApplicationTests.java b/api/src/test/java/ca/bc/gov/educ/api/gradbusiness/EducGradBusinessApiApplicationTests.java index 993d1f8..1a0f2ec 100644 --- a/api/src/test/java/ca/bc/gov/educ/api/gradbusiness/EducGradBusinessApiApplicationTests.java +++ b/api/src/test/java/ca/bc/gov/educ/api/gradbusiness/EducGradBusinessApiApplicationTests.java @@ -1,5 +1,6 @@ package ca.bc.gov.educ.api.gradbusiness; +import ca.bc.gov.educ.api.gradbusiness.exception.ServiceException; import ca.bc.gov.educ.api.gradbusiness.model.dto.Student; import ca.bc.gov.educ.api.gradbusiness.service.GradBusinessService; import ca.bc.gov.educ.api.gradbusiness.util.EducGradBusinessApiConstants; @@ -478,6 +479,7 @@ void testStudentTranscriptPDFByTypeByPen() throws Exception { when(this.requestBodyMock.contentType(any())).thenReturn(this.requestBodyMock); when(this.requestBodyMock.body(any(BodyInserter.class))).thenReturn(this.requestHeadersMock); when(this.requestHeadersMock.retrieve()).thenReturn(this.responseMock); + when(this.responseMock.onStatus(any(), any())).thenReturn(this.responseMock); when(this.responseMock.bodyToMono(byte[].class)).thenReturn(Mono.just(transcriptPdfSample)); when(this.tokenUtils.getAccessToken()).thenReturn("accessToken"); @@ -485,6 +487,21 @@ void testStudentTranscriptPDFByTypeByPen() throws Exception { ResponseEntity transcriptPdf = gradBusinessService.getStudentTranscriptPDFByType(pen, "xml", null,"accessToken"); assertNotNull(transcriptPdf.getBody()); assertEquals(transcriptPdfSample,transcriptPdf.getBody()); + + when(this.webClient.post()).thenReturn(this.requestBodyUriMock); + when(this.requestBodyUriMock.uri(educGraduationApiConstants.getStudentTranscriptReportByRequest())).thenReturn(this.requestBodyUriMock); + when(this.requestBodyUriMock.headers(any(Consumer.class))).thenReturn(this.requestBodyMock); + when(this.requestBodyMock.contentType(any())).thenReturn(this.requestBodyMock); + when(this.requestBodyMock.body(any(BodyInserter.class))).thenReturn(this.requestHeadersMock); + when(this.requestHeadersMock.retrieve()).thenReturn(this.responseMock); + when(this.responseMock.onStatus(any(), any())).thenReturn(this.responseMock); + when(this.responseMock.bodyToMono(byte[].class)).thenThrow(new ServiceException("NO_CONTENT", 204)); + + when(this.tokenUtils.getAccessToken()).thenReturn("accessToken"); + + transcriptPdf = gradBusinessService.getStudentTranscriptPDFByType(pen, "xml", null,"accessToken"); + assertNotNull(transcriptPdf); + assertNull(transcriptPdf.getBody()); } @Test