diff --git a/alfresco-docker-alfresco-pdf-renderer/pom.xml b/alfresco-docker-alfresco-pdf-renderer/pom.xml index f5724eac..65c02b4b 100644 --- a/alfresco-docker-alfresco-pdf-renderer/pom.xml +++ b/alfresco-docker-alfresco-pdf-renderer/pom.xml @@ -65,7 +65,6 @@ dom4j 2.1.1 - diff --git a/alfresco-docker-alfresco-pdf-renderer/src/main/java/org/alfresco/transformer/AlfrescoPdfRendererController.java b/alfresco-docker-alfresco-pdf-renderer/src/main/java/org/alfresco/transformer/AlfrescoPdfRendererController.java index 6c6988e0..0e62a056 100644 --- a/alfresco-docker-alfresco-pdf-renderer/src/main/java/org/alfresco/transformer/AlfrescoPdfRendererController.java +++ b/alfresco-docker-alfresco-pdf-renderer/src/main/java/org/alfresco/transformer/AlfrescoPdfRendererController.java @@ -30,11 +30,10 @@ import static org.alfresco.transformer.fs.FileManager.createAttachment; import static org.alfresco.transformer.fs.FileManager.createSourceFile; import static org.alfresco.transformer.fs.FileManager.createTargetFile; import static org.alfresco.transformer.fs.FileManager.createTargetFileName; -import static org.alfresco.transformer.logging.StandardMessages.LICENCE; import static org.springframework.http.HttpStatus.OK; +import static org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE; import java.io.File; -import java.util.Arrays; import java.util.Map; import javax.servlet.http.HttpServletRequest; @@ -46,7 +45,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; @@ -58,38 +56,30 @@ import org.springframework.web.multipart.MultipartFile; * * Status Codes: * - * 200 Success - * 400 Bad Request: Request parameter is missing (missing mandatory parameter) - * 400 Bad Request: Request parameter is of the wrong type - * 400 Bad Request: Transformer exit code was not 0 (possible problem with the source file) - * 400 Bad Request: The source filename was not supplied - * 500 Internal Server Error: (no message with low level IO problems) - * 500 Internal Server Error: The target filename was not supplied (should not happen as targetExtension is checked) - * 500 Internal Server Error: Transformer version check exit code was not 0 - * 500 Internal Server Error: Transformer version check failed to create any output - * 500 Internal Server Error: Could not read the target file - * 500 Internal Server Error: The target filename was malformed (should not happen because of other checks) - * 500 Internal Server Error: Transformer failed to create an output file (the exit code was 0, so there should be some content) - * 500 Internal Server Error: Filename encoding error - * 507 Insufficient Storage: Failed to store the source file + * 200 Success + * 400 Bad Request: Request parameter is missing (missing mandatory parameter) + * 400 Bad Request: Request parameter is of the wrong type + * 400 Bad Request: Transformer exit code was not 0 (possible problem with the source file) + * 400 Bad Request: The source filename was not supplied + * 500 Internal Server Error: (no message with low level IO problems) + * 500 Internal Server Error: The target filename was not supplied (should not happen as targetExtension is checked) + * 500 Internal Server Error: Transformer version check exit code was not 0 + * 500 Internal Server Error: Transformer version check failed to create any output + * 500 Internal Server Error: Could not read the target file + * 500 Internal Server Error: The target filename was malformed (should not happen because of other checks) + * 500 Internal Server Error: Transformer failed to create an output file (the exit code was 0, so there should be some content) + * 500 Internal Server Error: Filename encoding error + * 507 Insufficient Storage: Failed to store the source file */ @Controller public class AlfrescoPdfRendererController extends AbstractTransformerController { - private static final Logger logger = LoggerFactory.getLogger(AlfrescoPdfRendererController.class); + private static final Logger logger = LoggerFactory.getLogger( + AlfrescoPdfRendererController.class); @Autowired private PdfRendererCommandExecutor commandExecutor; - @Autowired - public AlfrescoPdfRendererController() - { - logger.info("-----------------------------------------------------------------------------------------------------------------------------------------------------------"); - Arrays.stream(LICENCE.split("\\n")).forEach(logger::info); - logger.info("alfresco-pdf-renderer uses the PDFium library from Google Inc. See the license at https://pdfium.googlesource.com/pdfium/+/master/LICENSE or in /pdfium.txt"); - logger.info("-----------------------------------------------------------------------------------------------------------------------------------------------------------"); - } - @Override public String getTransformerName() { @@ -137,20 +127,21 @@ public class AlfrescoPdfRendererController extends AbstractTransformerController } @Deprecated - @PostMapping(value = "/transform", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @PostMapping(value = "/transform", consumes = MULTIPART_FORM_DATA_VALUE) public ResponseEntity transform(HttpServletRequest request, - @RequestParam("file") MultipartFile sourceMultipartFile, - @RequestParam("targetExtension") String targetExtension, - @RequestParam(value = "timeout", required = false) Long timeout, - @RequestParam(value = "testDelay", required = false) Long testDelay, + @RequestParam("file") MultipartFile sourceMultipartFile, + @RequestParam("targetExtension") String targetExtension, + @RequestParam(value = "timeout", required = false) Long timeout, + @RequestParam(value = "testDelay", required = false) Long testDelay, - @RequestParam(value = "page", required = false) Integer page, - @RequestParam(value = "width", required = false) Integer width, - @RequestParam(value = "height", required = false) Integer height, - @RequestParam(value = "allowPdfEnlargement", required = false) Boolean allowPdfEnlargement, - @RequestParam(value = "maintainPdfAspectRatio", required = false) Boolean maintainPdfAspectRatio) + @RequestParam(value = "page", required = false) Integer page, + @RequestParam(value = "width", required = false) Integer width, + @RequestParam(value = "height", required = false) Integer height, + @RequestParam(value = "allowPdfEnlargement", required = false) Boolean allowPdfEnlargement, + @RequestParam(value = "maintainPdfAspectRatio", required = false) Boolean maintainPdfAspectRatio) { - String targetFilename = createTargetFileName(sourceMultipartFile.getOriginalFilename(), targetExtension); + String targetFilename = createTargetFileName(sourceMultipartFile.getOriginalFilename(), + targetExtension); getProbeTestTransform().incrementTransformerCount(); File sourceFile = createSourceFile(request, sourceMultipartFile); File targetFile = createTargetFile(request, targetFilename); diff --git a/alfresco-docker-alfresco-pdf-renderer/src/main/java/org/alfresco/transformer/Application.java b/alfresco-docker-alfresco-pdf-renderer/src/main/java/org/alfresco/transformer/Application.java index 4d0173ef..46b49c08 100644 --- a/alfresco-docker-alfresco-pdf-renderer/src/main/java/org/alfresco/transformer/Application.java +++ b/alfresco-docker-alfresco-pdf-renderer/src/main/java/org/alfresco/transformer/Application.java @@ -26,30 +26,52 @@ */ package org.alfresco.transformer; +import static org.alfresco.transformer.logging.StandardMessages.LICENCE; + +import java.util.Arrays; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.annotation.Bean; +import org.springframework.context.event.EventListener; import io.micrometer.core.instrument.MeterRegistry; @SpringBootApplication -@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) +@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class}) public class Application { + private static final Logger logger = LoggerFactory.getLogger(Application.class); + @Value("${container.name}") private String containerName; @Bean - public MeterRegistryCustomizer metricsCommonTags() { + public MeterRegistryCustomizer metricsCommonTags() + { return registry -> registry.config().commonTags("containerName", containerName); } - + public static void main(String[] args) { SpringApplication.run(Application.class, args); } + + @EventListener(ApplicationReadyEvent.class) + public void startup() + { + logger.info("-----------------------------------------------------------------------------------------------------------------------------------------------------------"); + Arrays.stream(LICENCE.split("\\n")).forEach(logger::info); + logger.info("alfresco-pdf-renderer uses the PDFium library from Google Inc. See the license at https://pdfium.googlesource.com/pdfium/+/master/LICENSE or in /pdfium.txt"); + logger.info("-----------------------------------------------------------------------------------------------------------------------------------------------------------"); + + logger.info("Starting application components... Done"); + } } diff --git a/alfresco-docker-alfresco-pdf-renderer/src/main/java/org/alfresco/transformer/OptionsBuilder.java b/alfresco-docker-alfresco-pdf-renderer/src/main/java/org/alfresco/transformer/OptionsBuilder.java index b49267ae..36c6a407 100644 --- a/alfresco-docker-alfresco-pdf-renderer/src/main/java/org/alfresco/transformer/OptionsBuilder.java +++ b/alfresco-docker-alfresco-pdf-renderer/src/main/java/org/alfresco/transformer/OptionsBuilder.java @@ -44,9 +44,7 @@ final class OptionsBuilder private Boolean allowPdfEnlargement; private Boolean maintainPdfAspectRatio; - private OptionsBuilder() - { - } + private OptionsBuilder() {} public OptionsBuilder withPage(final String page) { diff --git a/alfresco-docker-alfresco-pdf-renderer/src/main/java/org/alfresco/transformer/executors/PdfRendererCommandExecutor.java b/alfresco-docker-alfresco-pdf-renderer/src/main/java/org/alfresco/transformer/executors/PdfRendererCommandExecutor.java index 12019e90..c79900ed 100644 --- a/alfresco-docker-alfresco-pdf-renderer/src/main/java/org/alfresco/transformer/executors/PdfRendererCommandExecutor.java +++ b/alfresco-docker-alfresco-pdf-renderer/src/main/java/org/alfresco/transformer/executors/PdfRendererCommandExecutor.java @@ -33,7 +33,7 @@ import org.alfresco.util.exec.RuntimeExec; import org.springframework.stereotype.Component; /** - * CommandExecutor implementation for running PDF Renderer transformations. It runs the + * CommandExecutor implementation for running PDF Renderer transformations. It runs the * transformation logic as a separate Shell process. */ @Component diff --git a/alfresco-docker-alfresco-pdf-renderer/src/test/java/org/alfresco/transformer/AlfrescoPdfRendererControllerTest.java b/alfresco-docker-alfresco-pdf-renderer/src/test/java/org/alfresco/transformer/AlfrescoPdfRendererControllerTest.java index 921f88f4..3c21840a 100644 --- a/alfresco-docker-alfresco-pdf-renderer/src/test/java/org/alfresco/transformer/AlfrescoPdfRendererControllerTest.java +++ b/alfresco-docker-alfresco-pdf-renderer/src/test/java/org/alfresco/transformer/AlfrescoPdfRendererControllerTest.java @@ -33,11 +33,19 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.when; +import static org.springframework.http.HttpHeaders.ACCEPT; +import static org.springframework.http.HttpHeaders.CONTENT_DISPOSITION; +import static org.springframework.http.HttpHeaders.CONTENT_TYPE; import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.CREATED; import static org.springframework.http.HttpStatus.OK; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; +import static org.springframework.http.MediaType.APPLICATION_PDF_VALUE; +import static org.springframework.http.MediaType.IMAGE_PNG_VALUE; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.util.StringUtils.getFilenameExtension; import java.io.File; import java.io.IOException; @@ -64,14 +72,11 @@ import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.mock.web.MockMultipartFile; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -import org.springframework.util.StringUtils; /** * Test the AlfrescoPdfRendererController without a server. @@ -101,7 +106,7 @@ public class AlfrescoPdfRendererControllerTest extends AbstractTransformerContro { ReflectionTestUtils.setField(commandExecutor, "transformCommand", mockTransformCommand); ReflectionTestUtils.setField(commandExecutor, "checkCommand", mockCheckCommand); - + mockTransformCommand("pdf", "png", "application/pdf", true); } @@ -118,7 +123,8 @@ public class AlfrescoPdfRendererControllerTest extends AbstractTransformerContro expectedSourceSuffix = null; expectedSourceFileBytes = readTestFile(sourceExtension); expectedTargetFileBytes = readTargetFileBytes ? readTestFile(targetExtension) : null; - sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype, expectedSourceFileBytes); + sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype, + expectedSourceFileBytes); when(mockTransformCommand.execute(any(), anyLong())).thenAnswer( (Answer) invocation -> { @@ -128,14 +134,17 @@ public class AlfrescoPdfRendererControllerTest extends AbstractTransformerContro String actualOptions = actualProperties.get("options"); String actualSource = actualProperties.get("source"); String actualTarget = actualProperties.get("target"); - String actualTargetExtension = StringUtils.getFilenameExtension(actualTarget); + String actualTargetExtension = getFilenameExtension(actualTarget); assertNotNull(actualSource); assertNotNull(actualTarget); if (expectedSourceSuffix != null) { - assertTrue("The source file \""+actualSource+"\" should have ended in \""+expectedSourceSuffix+"\"", actualSource.endsWith(expectedSourceSuffix)); - actualSource = actualSource.substring(0, actualSource.length()-expectedSourceSuffix.length()); + assertTrue("The source file \"" + actualSource + + "\" should have ended in \"" + expectedSourceSuffix + "\"", + actualSource.endsWith(expectedSourceSuffix)); + actualSource = actualSource.substring(0, + actualSource.length() - expectedSourceSuffix.length()); } assertNotNull(actualOptions); @@ -155,7 +164,7 @@ public class AlfrescoPdfRendererControllerTest extends AbstractTransformerContro int i = actualTarget.lastIndexOf('_'); if (i >= 0) { - String testFilename = actualTarget.substring(i+1); + String testFilename = actualTarget.substring(i + 1); File testFile = getTestFile(testFilename, false); File targetFile = new File(actualTarget); generateTargetFileFromResourceFile(actualTargetExtension, testFile, @@ -164,7 +173,8 @@ public class AlfrescoPdfRendererControllerTest extends AbstractTransformerContro // Check the supplied source file has not been changed. byte[] actualSourceFileBytes = Files.readAllBytes(new File(actualSource).toPath()); - assertTrue("Source file is not the same", Arrays.equals(expectedSourceFileBytes, actualSourceFileBytes)); + assertTrue("Source file is not the same", + Arrays.equals(expectedSourceFileBytes, actualSourceFileBytes)); return mockExecutionResult; }); @@ -174,7 +184,6 @@ public class AlfrescoPdfRendererControllerTest extends AbstractTransformerContro when(mockExecutionResult.getStdOut()).thenReturn("STDOUT"); } - @Override protected AbstractTransformerController getController() { @@ -185,7 +194,9 @@ public class AlfrescoPdfRendererControllerTest extends AbstractTransformerContro public void optionsTest() throws Exception { expectedOptions = "--width=321 --height=654 --allow-enlargement --maintain-aspect-ratio --page=2"; - mockMvc.perform(MockMvcRequestBuilders.multipart("/transform") + mockMvc + .perform(MockMvcRequestBuilders + .multipart("/transform") .file(sourceFile) .param("targetExtension", targetExtension) @@ -195,17 +206,19 @@ public class AlfrescoPdfRendererControllerTest extends AbstractTransformerContro .param("height", "654") .param("allowPdfEnlargement", "true") .param("maintainPdfAspectRatio", "true")) - - .andExpect(status().is(OK.value())) - .andExpect(content().bytes(expectedTargetFileBytes)) - .andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''quick."+targetExtension)); + .andExpect(status().is(OK.value())) + .andExpect(content().bytes(expectedTargetFileBytes)) + .andExpect(header().string("Content-Disposition", + "attachment; filename*= UTF-8''quick." + targetExtension)); } @Test public void optionsNegateBooleansTest() throws Exception { expectedOptions = "--width=321 --height=654 --page=2"; - mockMvc.perform(MockMvcRequestBuilders.multipart("/transform") + mockMvc + .perform(MockMvcRequestBuilders + .multipart("/transform") .file(sourceFile) .param("targetExtension", targetExtension) @@ -215,10 +228,10 @@ public class AlfrescoPdfRendererControllerTest extends AbstractTransformerContro .param("height", "654") .param("allowPdfEnlargement", "false") .param("maintainPdfAspectRatio", "false")) - - .andExpect(status().is(OK.value())) - .andExpect(content().bytes(expectedTargetFileBytes)) - .andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''quick."+targetExtension)); + .andExpect(status().is(OK.value())) + .andExpect(content().bytes(expectedTargetFileBytes)) + .andExpect(header().string("Content-Disposition", + "attachment; filename*= UTF-8''quick." + targetExtension)); } @Override @@ -226,8 +239,8 @@ public class AlfrescoPdfRendererControllerTest extends AbstractTransformerContro { transformRequest.setSourceExtension("pdf"); transformRequest.setTargetExtension("png"); - transformRequest.setSourceMediaType(MediaType.APPLICATION_PDF_VALUE); - transformRequest.setTargetMediaType(MediaType.IMAGE_PNG_VALUE); + transformRequest.setSourceMediaType(APPLICATION_PDF_VALUE); + transformRequest.setTargetMediaType(IMAGE_PNG_VALUE); } @Test @@ -237,7 +250,8 @@ public class AlfrescoPdfRendererControllerTest extends AbstractTransformerContro mockMvc.perform(mockMvcRequest("/transform", sourceFile, "targetExtension", "xxx")) .andExpect(status().is(BAD_REQUEST.value())) - .andExpect(status().reason(containsString("Transformer exit code was not 0: \nSTDERR"))); + .andExpect(status() + .reason(containsString("Transformer exit code was not 0: \nSTDERR"))); } @Test @@ -248,7 +262,6 @@ public class AlfrescoPdfRendererControllerTest extends AbstractTransformerContro File sourceFile = getTestFile("quick." + sourceExtension, true); String targetFileRef = UUID.randomUUID().toString(); - // Transformation Request POJO TransformRequest transformRequest = new TransformRequest(); transformRequest.setRequestId("1"); @@ -262,12 +275,13 @@ public class AlfrescoPdfRendererControllerTest extends AbstractTransformerContro // HTTP Request HttpHeaders headers = new HttpHeaders(); - headers.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=quick." + sourceExtension); + headers.set(CONTENT_DISPOSITION, "attachment; filename=quick." + sourceExtension); ResponseEntity response = new ResponseEntity<>(new FileSystemResource( sourceFile), headers, OK); when(alfrescoSharedFileStoreClient.retrieveFile(sourceFileRef)).thenReturn(response); - when(alfrescoSharedFileStoreClient.saveFile(any())).thenReturn(new FileRefResponse(new FileRefEntity(targetFileRef))); + when(alfrescoSharedFileStoreClient.saveFile(any())) + .thenReturn(new FileRefResponse(new FileRefEntity(targetFileRef))); when(mockExecutionResult.getExitValue()).thenReturn(0); // Update the Transformation Request with any specific params before sending it @@ -275,18 +289,21 @@ public class AlfrescoPdfRendererControllerTest extends AbstractTransformerContro // Serialize and call the transformer String tr = objectMapper.writeValueAsString(transformRequest); - String transformationReplyAsString = mockMvc.perform(MockMvcRequestBuilders.post("/transform") - .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).content(tr)) - .andExpect(status().is(HttpStatus.CREATED.value())) - .andReturn().getResponse().getContentAsString(); + String transformationReplyAsString = mockMvc + .perform(MockMvcRequestBuilders + .post("/transform") + .header(ACCEPT, APPLICATION_JSON_VALUE) + .header(CONTENT_TYPE, APPLICATION_JSON_VALUE) + .content(tr)) + .andExpect(status().is(CREATED.value())) + .andReturn().getResponse().getContentAsString(); - TransformReply transformReply = objectMapper.readValue(transformationReplyAsString, TransformReply.class); + TransformReply transformReply = objectMapper.readValue(transformationReplyAsString, + TransformReply.class); // Assert the reply assertEquals(transformRequest.getRequestId(), transformReply.getRequestId()); assertEquals(transformRequest.getClientData(), transformReply.getClientData()); assertEquals(transformRequest.getSchema(), transformReply.getSchema()); } - } diff --git a/alfresco-docker-alfresco-pdf-renderer/src/test/java/org/alfresco/transformer/AlfrescoPdfRendererQueueTransformServiceIT.java b/alfresco-docker-alfresco-pdf-renderer/src/test/java/org/alfresco/transformer/AlfrescoPdfRendererQueueTransformServiceIT.java index 31a3c5ec..3fdba980 100644 --- a/alfresco-docker-alfresco-pdf-renderer/src/test/java/org/alfresco/transformer/AlfrescoPdfRendererQueueTransformServiceIT.java +++ b/alfresco-docker-alfresco-pdf-renderer/src/test/java/org/alfresco/transformer/AlfrescoPdfRendererQueueTransformServiceIT.java @@ -48,7 +48,8 @@ public class AlfrescoPdfRendererQueueTransformServiceIT extends AbstractQueueTra @Override protected TransformRequest buildRequest() { - return TransformRequest.builder() + return TransformRequest + .builder() .withRequestId(UUID.randomUUID().toString()) .withSourceMediaType(MIMETYPE_OPENXML_WORDPROCESSING) .withTargetMediaType(MIMETYPE_PDF) diff --git a/alfresco-docker-imagemagick/pom.xml b/alfresco-docker-imagemagick/pom.xml index b419ca88..b965292e 100644 --- a/alfresco-docker-imagemagick/pom.xml +++ b/alfresco-docker-imagemagick/pom.xml @@ -65,7 +65,6 @@ dom4j 2.1.1 - diff --git a/alfresco-docker-imagemagick/src/main/java/org/alfresco/transformer/Application.java b/alfresco-docker-imagemagick/src/main/java/org/alfresco/transformer/Application.java index 956b7a60..f2e907f0 100644 --- a/alfresco-docker-imagemagick/src/main/java/org/alfresco/transformer/Application.java +++ b/alfresco-docker-imagemagick/src/main/java/org/alfresco/transformer/Application.java @@ -26,30 +26,52 @@ */ package org.alfresco.transformer; +import static org.alfresco.transformer.logging.StandardMessages.LICENCE; + +import java.util.Arrays; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.annotation.Bean; +import org.springframework.context.event.EventListener; import io.micrometer.core.instrument.MeterRegistry; @SpringBootApplication -@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) +@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class}) public class Application { + private static final Logger logger = LoggerFactory.getLogger(Application.class); + @Value("${container.name}") private String containerName; @Bean - MeterRegistryCustomizer metricsCommonTags() { + MeterRegistryCustomizer metricsCommonTags() + { return registry -> registry.config().commonTags("containerName", containerName); } - + public static void main(String[] args) { SpringApplication.run(Application.class, args); } + + @EventListener(ApplicationReadyEvent.class) + public void startup() + { + logger.info("--------------------------------------------------------------------------------------------------------------------------------------------------------------"); + Arrays.stream(LICENCE.split("\\n")).forEach(logger::info); + logger.info("This transformer uses ImageMagick from ImageMagick Studio LLC. See the license at http://www.imagemagick.org/script/license.php or in /ImageMagick-license.txt"); + logger.info("--------------------------------------------------------------------------------------------------------------------------------------------------------------"); + + logger.info("Starting application components... Done"); + } } diff --git a/alfresco-docker-imagemagick/src/main/java/org/alfresco/transformer/ImageMagickController.java b/alfresco-docker-imagemagick/src/main/java/org/alfresco/transformer/ImageMagickController.java index a6042f31..da020a5e 100644 --- a/alfresco-docker-imagemagick/src/main/java/org/alfresco/transformer/ImageMagickController.java +++ b/alfresco-docker-imagemagick/src/main/java/org/alfresco/transformer/ImageMagickController.java @@ -30,24 +30,22 @@ import static org.alfresco.transformer.fs.FileManager.createAttachment; import static org.alfresco.transformer.fs.FileManager.createSourceFile; import static org.alfresco.transformer.fs.FileManager.createTargetFile; import static org.alfresco.transformer.fs.FileManager.createTargetFileName; -import static org.alfresco.transformer.logging.StandardMessages.LICENCE; import static org.alfresco.transformer.util.Util.stringToInteger; import static org.springframework.http.HttpStatus.OK; +import static org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE; import java.io.File; -import java.util.Arrays; import java.util.Map; import javax.servlet.http.HttpServletRequest; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.alfresco.transformer.executors.ImageMagickCommandExecutor; import org.alfresco.transformer.logging.LogEntry; import org.alfresco.transformer.probes.ProbeTestTransform; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; @@ -60,21 +58,21 @@ import org.springframework.web.multipart.MultipartFile; * * Status Codes: * - * 200 Success - * 400 Bad Request: Invalid cropGravity value (North, NorthEast, East, SouthEast, South, SouthWest, West, NorthWest, Center) - * 400 Bad Request: Request parameter is missing (missing mandatory parameter) - * 400 Bad Request: Request parameter is of the wrong type - * 400 Bad Request: Transformer exit code was not 0 (possible problem with the source file) - * 400 Bad Request: The source filename was not supplied - * 500 Internal Server Error: (no message with low level IO problems) - * 500 Internal Server Error: The target filename was not supplied (should not happen as targetExtension is checked) - * 500 Internal Server Error: Transformer version check exit code was not 0 - * 500 Internal Server Error: Transformer version check failed to create any output - * 500 Internal Server Error: Could not read the target file - * 500 Internal Server Error: The target filename was malformed (should not happen because of other checks) - * 500 Internal Server Error: Transformer failed to create an output file (the exit code was 0, so there should be some content) - * 500 Internal Server Error: Filename encoding error - * 507 Insufficient Storage: Failed to store the source file + * 200 Success + * 400 Bad Request: Invalid cropGravity value (North, NorthEast, East, SouthEast, South, SouthWest, West, NorthWest, Center) + * 400 Bad Request: Request parameter is missing (missing mandatory parameter) + * 400 Bad Request: Request parameter is of the wrong type + * 400 Bad Request: Transformer exit code was not 0 (possible problem with the source file) + * 400 Bad Request: The source filename was not supplied + * 500 Internal Server Error: (no message with low level IO problems) + * 500 Internal Server Error: The target filename was not supplied (should not happen as targetExtension is checked) + * 500 Internal Server Error: Transformer version check exit code was not 0 + * 500 Internal Server Error: Transformer version check failed to create any output + * 500 Internal Server Error: Could not read the target file + * 500 Internal Server Error: The target filename was malformed (should not happen because of other checks) + * 500 Internal Server Error: Transformer failed to create an output file (the exit code was 0, so there should be some content) + * 500 Internal Server Error: Filename encoding error + * 507 Insufficient Storage: Failed to store the source file */ @Controller public class ImageMagickController extends AbstractTransformerController @@ -83,15 +81,6 @@ public class ImageMagickController extends AbstractTransformerController @Autowired private ImageMagickCommandExecutor commandExecutor; - - @Autowired - public ImageMagickController() - { - logger.info("--------------------------------------------------------------------------------------------------------------------------------------------------------------"); - Arrays.stream(LICENCE.split("\\n")).forEach(logger::info); - logger.info("This transformer uses ImageMagick from ImageMagick Studio LLC. See the license at http://www.imagemagick.org/script/license.php or in /ImageMagick-license.txt"); - logger.info("--------------------------------------------------------------------------------------------------------------------------------------------------------------"); - } @Override public String getTransformerName() @@ -110,7 +99,7 @@ public class ImageMagickController extends AbstractTransformerController { // See the Javadoc on this method and Probes.md for the choice of these values. return new ProbeTestTransform(this, "quick.jpg", "quick.png", - 35593, 1024, 150, 1024, 60*15+1,60*15) + 35593, 1024, 150, 1024, 60 * 15 + 1, 60 * 15) { @Override protected void executeTransformCommand(File sourceFile, File targetFile) @@ -120,44 +109,44 @@ public class ImageMagickController extends AbstractTransformerController }; } - @PostMapping(value = "/transform", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @PostMapping(value = "/transform", consumes = MULTIPART_FORM_DATA_VALUE) public ResponseEntity transform(HttpServletRequest request, - @RequestParam("file") MultipartFile sourceMultipartFile, - @RequestParam("targetExtension") String targetExtension, - @RequestParam(value = "timeout", required = false) Long timeout, - @RequestParam(value = "testDelay", required = false) Long testDelay, + @RequestParam("file") MultipartFile sourceMultipartFile, + @RequestParam("targetExtension") String targetExtension, + @RequestParam(value = "timeout", required = false) Long timeout, + @RequestParam(value = "testDelay", required = false) Long testDelay, - @RequestParam(value = "startPage", required = false) Integer startPage, - @RequestParam(value = "endPage", required = false) Integer endPage, + @RequestParam(value = "startPage", required = false) Integer startPage, + @RequestParam(value = "endPage", required = false) Integer endPage, - @RequestParam(value = "alphaRemove", required = false) Boolean alphaRemove, - @RequestParam(value = "autoOrient", required = false) Boolean autoOrient, + @RequestParam(value = "alphaRemove", required = false) Boolean alphaRemove, + @RequestParam(value = "autoOrient", required = false) Boolean autoOrient, - @RequestParam(value = "cropGravity", required = false) String cropGravity, - @RequestParam(value = "cropWidth", required = false) Integer cropWidth, - @RequestParam(value = "cropHeight", required = false) Integer cropHeight, - @RequestParam(value = "cropPercentage", required = false) Boolean cropPercentage, - @RequestParam(value = "cropXOffset", required = false) Integer cropXOffset, - @RequestParam(value = "cropYOffset", required = false) Integer cropYOffset, + @RequestParam(value = "cropGravity", required = false) String cropGravity, + @RequestParam(value = "cropWidth", required = false) Integer cropWidth, + @RequestParam(value = "cropHeight", required = false) Integer cropHeight, + @RequestParam(value = "cropPercentage", required = false) Boolean cropPercentage, + @RequestParam(value = "cropXOffset", required = false) Integer cropXOffset, + @RequestParam(value = "cropYOffset", required = false) Integer cropYOffset, - @RequestParam(value = "thumbnail", required = false) Boolean thumbnail, - @RequestParam(value = "resizeWidth", required = false) Integer resizeWidth, - @RequestParam(value = "resizeHeight", required = false) Integer resizeHeight, - @RequestParam(value = "resizePercentage", required = false) Boolean resizePercentage, - @RequestParam(value = "allowEnlargement", required = false) Boolean allowEnlargement, - @RequestParam(value = "maintainAspectRatio", required = false) Boolean maintainAspectRatio, + @RequestParam(value = "thumbnail", required = false) Boolean thumbnail, + @RequestParam(value = "resizeWidth", required = false) Integer resizeWidth, + @RequestParam(value = "resizeHeight", required = false) Integer resizeHeight, + @RequestParam(value = "resizePercentage", required = false) Boolean resizePercentage, + @RequestParam(value = "allowEnlargement", required = false) Boolean allowEnlargement, + @RequestParam(value = "maintainAspectRatio", required = false) Boolean maintainAspectRatio, - // The commandOptions parameter is supported in ACS 6.0.1 because there may be - // custom renditions that use it. However the Transform service should - // not support it as it provides the option to specify arbitrary command - // options or even the option to run something else on the command line. - // All Transform service options should be checked as is done for the other - // request parameters. Setting this option in the rendition's - // ImageTransformationOptions object is being deprecated for the point where - // The Transform service is being used for all transforms. In the case of - // ACS 6.0, this is relatively safe as it requires an AMP to be installed - // which supplies the commandOptions. - @RequestParam(value = "commandOptions", required = false) String commandOptions) + // The commandOptions parameter is supported in ACS 6.0.1 because there may be + // custom renditions that use it. However the Transform service should + // not support it as it provides the option to specify arbitrary command + // options or even the option to run something else on the command line. + // All Transform service options should be checked as is done for the other + // request parameters. Setting this option in the rendition's + // ImageTransformationOptions object is being deprecated for the point where + // The Transform service is being used for all transforms. In the case of + // ACS 6.0, this is relatively safe as it requires an AMP to be installed + // which supplies the commandOptions. + @RequestParam(value = "commandOptions", required = false) String commandOptions) { String targetFilename = createTargetFileName(sourceMultipartFile.getOriginalFilename(), targetExtension); @@ -238,11 +227,11 @@ public class ImageMagickController extends AbstractTransformerController private static String calculatePageRange(Integer startPage, Integer endPage) { return startPage == null - ? endPage == null - ? "" - : "["+endPage+']' - : endPage == null || startPage.equals(endPage) - ? "["+startPage+']' - : "["+startPage+'-'+endPage+']'; + ? endPage == null + ? "" + : "[" + endPage + ']' + : endPage == null || startPage.equals(endPage) + ? "[" + startPage + ']' + : "[" + startPage + '-' + endPage + ']'; } } diff --git a/alfresco-docker-imagemagick/src/main/java/org/alfresco/transformer/OptionsBuilder.java b/alfresco-docker-imagemagick/src/main/java/org/alfresco/transformer/OptionsBuilder.java index b015ec3f..2c1e08da 100644 --- a/alfresco-docker-imagemagick/src/main/java/org/alfresco/transformer/OptionsBuilder.java +++ b/alfresco-docker-imagemagick/src/main/java/org/alfresco/transformer/OptionsBuilder.java @@ -26,7 +26,6 @@ */ package org.alfresco.transformer; -import static java.util.Arrays.asList; import static org.alfresco.transformer.util.Util.stringToBoolean; import static org.alfresco.transformer.util.Util.stringToInteger; import static org.springframework.http.HttpStatus.BAD_REQUEST; @@ -36,6 +35,8 @@ import java.util.StringJoiner; import org.alfresco.transform.exceptions.TransformException; +import com.google.common.collect.ImmutableList; + /** * ImageMagick options builder. * @@ -43,8 +44,8 @@ import org.alfresco.transform.exceptions.TransformException; */ final class OptionsBuilder { - private static final List GRAVITY_VALUES = asList("North", "NorthEast", "East", - "SouthEast", "South", "SouthWest", "West", "NorthWest", "Center"); + private static final List GRAVITY_VALUES = ImmutableList.of("North", "NorthEast", + "East", "SouthEast", "South", "SouthWest", "West", "NorthWest", "Center"); private Integer startPage; private Integer endPage; @@ -64,9 +65,7 @@ final class OptionsBuilder private Boolean maintainAspectRatio; private String commandOptions; - private OptionsBuilder() - { - } + private OptionsBuilder() {} public OptionsBuilder withStartPage(final String startPage) { diff --git a/alfresco-docker-imagemagick/src/main/java/org/alfresco/transformer/executors/ImageMagickCommandExecutor.java b/alfresco-docker-imagemagick/src/main/java/org/alfresco/transformer/executors/ImageMagickCommandExecutor.java index 2fce9b8b..f6329d6a 100644 --- a/alfresco-docker-imagemagick/src/main/java/org/alfresco/transformer/executors/ImageMagickCommandExecutor.java +++ b/alfresco-docker-imagemagick/src/main/java/org/alfresco/transformer/executors/ImageMagickCommandExecutor.java @@ -33,7 +33,7 @@ import org.alfresco.util.exec.RuntimeExec; import org.springframework.stereotype.Component; /** - * CommandExecutor implementation for running ImageMagick transformations. It runs the + * CommandExecutor implementation for running ImageMagick transformations. It runs the * transformation logic as a separate Shell process. */ @Component @@ -42,7 +42,7 @@ public class ImageMagickCommandExecutor extends AbstractCommandExecutor private static final String ROOT = "/usr/lib64/ImageMagick-7.0.7"; private static final String DYN = ROOT + "/lib"; private static final String EXE = "/usr/bin/convert"; - + @Override protected RuntimeExec createTransformCommand() { diff --git a/alfresco-docker-imagemagick/src/test/java/org/alfresco/transformer/ImageMagickControllerTest.java b/alfresco-docker-imagemagick/src/test/java/org/alfresco/transformer/ImageMagickControllerTest.java index c5232ac0..e3244f2a 100644 --- a/alfresco-docker-imagemagick/src/test/java/org/alfresco/transformer/ImageMagickControllerTest.java +++ b/alfresco-docker-imagemagick/src/test/java/org/alfresco/transformer/ImageMagickControllerTest.java @@ -33,11 +33,18 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.when; +import static org.springframework.http.HttpHeaders.ACCEPT; +import static org.springframework.http.HttpHeaders.CONTENT_DISPOSITION; +import static org.springframework.http.HttpHeaders.CONTENT_TYPE; import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.CREATED; import static org.springframework.http.HttpStatus.OK; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; +import static org.springframework.http.MediaType.IMAGE_PNG_VALUE; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.util.StringUtils.getFilenameExtension; import java.io.File; import java.io.IOException; @@ -63,14 +70,11 @@ import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.mock.web.MockMultipartFile; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -import org.springframework.util.StringUtils; /** * Test the ImageMagickController without a server. @@ -91,7 +95,7 @@ public class ImageMagickControllerTest extends AbstractTransformerControllerTest @SpyBean private ImageMagickCommandExecutor commandExecutor; - + @SpyBean private ImageMagickController controller; @@ -117,7 +121,8 @@ public class ImageMagickControllerTest extends AbstractTransformerControllerTest expectedSourceSuffix = null; expectedSourceFileBytes = readTestFile(sourceExtension); expectedTargetFileBytes = readTargetFileBytes ? readTestFile(targetExtension) : null; - sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype, expectedSourceFileBytes); + sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype, + expectedSourceFileBytes); when(mockTransformCommand.execute(any(), anyLong())).thenAnswer( (Answer) invocation -> { @@ -127,14 +132,17 @@ public class ImageMagickControllerTest extends AbstractTransformerControllerTest String actualOptions = actualProperties.get("options"); String actualSource = actualProperties.get("source"); String actualTarget = actualProperties.get("target"); - String actualTargetExtension = StringUtils.getFilenameExtension(actualTarget); + String actualTargetExtension = getFilenameExtension(actualTarget); assertNotNull(actualSource); assertNotNull(actualTarget); if (expectedSourceSuffix != null) { - assertTrue("The source file \""+actualSource+"\" should have ended in \""+expectedSourceSuffix+"\"", actualSource.endsWith(expectedSourceSuffix)); - actualSource = actualSource.substring(0, actualSource.length()-expectedSourceSuffix.length()); + assertTrue( + "The source file \"" + actualSource + "\" should have ended in \"" + expectedSourceSuffix + "\"", + actualSource.endsWith(expectedSourceSuffix)); + actualSource = actualSource.substring(0, + actualSource.length() - expectedSourceSuffix.length()); } assertNotNull(actualOptions); @@ -154,7 +162,7 @@ public class ImageMagickControllerTest extends AbstractTransformerControllerTest int i = actualTarget.lastIndexOf('_'); if (i >= 0) { - String testFilename = actualTarget.substring(i+1); + String testFilename = actualTarget.substring(i + 1); File testFile = getTestFile(testFilename, false); File targetFile = new File(actualTarget); generateTargetFileFromResourceFile(actualTargetExtension, testFile, @@ -163,7 +171,8 @@ public class ImageMagickControllerTest extends AbstractTransformerControllerTest // Check the supplied source file has not been changed. byte[] actualSourceFileBytes = Files.readAllBytes(new File(actualSource).toPath()); - assertTrue("Source file is not the same", Arrays.equals(expectedSourceFileBytes, actualSourceFileBytes)); + assertTrue("Source file is not the same", + Arrays.equals(expectedSourceFileBytes, actualSourceFileBytes)); return mockExecutionResult; }); @@ -173,7 +182,6 @@ public class ImageMagickControllerTest extends AbstractTransformerControllerTest when(mockExecutionResult.getStdOut()).thenReturn("STDOUT"); } - @Override protected AbstractTransformerController getController() { @@ -183,27 +191,32 @@ public class ImageMagickControllerTest extends AbstractTransformerControllerTest @Test public void cropGravityGoodTest() throws Exception { - for (String value: new String[] {"North", "NorthEast", "East", "SouthEast", "South", "SouthWest", "West", "NorthWest", "Center"}) + for (String value : new String[]{"North", "NorthEast", "East", "SouthEast", "South", "SouthWest", "West", "NorthWest", "Center"}) { - expectedOptions = "-gravity "+value+" +repage"; - mockMvc.perform(MockMvcRequestBuilders.multipart("/transform") + expectedOptions = "-gravity " + value + " +repage"; + mockMvc + .perform(MockMvcRequestBuilders + .multipart("/transform") .file(sourceFile) .param("targetExtension", targetExtension) .param("cropGravity", value)) - .andExpect(status().is(OK.value())) - .andExpect(content().bytes(expectedTargetFileBytes)) - .andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''quick."+targetExtension)); + .andExpect(status().is(OK.value())) + .andExpect(content().bytes(expectedTargetFileBytes)) + .andExpect(header().string("Content-Disposition", + "attachment; filename*= UTF-8''quick." + targetExtension)); } } @Test public void cropGravityBadTest() throws Exception { - mockMvc.perform(MockMvcRequestBuilders.multipart("/transform") + mockMvc + .perform(MockMvcRequestBuilders + .multipart("/transform") .file(sourceFile) .param("targetExtension", targetExtension) .param("cropGravity", "badValue")) - .andExpect(status().is(BAD_REQUEST.value())); + .andExpect(status().is(BAD_REQUEST.value())); } @Test @@ -211,7 +224,9 @@ public class ImageMagickControllerTest extends AbstractTransformerControllerTest { expectedOptions = "-alpha remove -gravity SouthEast -crop 123x456%+90+12 +repage -thumbnail 321x654%!"; expectedSourceSuffix = "[2-3]"; - mockMvc.perform(MockMvcRequestBuilders.multipart("/transform") + mockMvc + .perform(MockMvcRequestBuilders + .multipart("/transform") .file(sourceFile) .param("targetExtension", targetExtension) @@ -234,10 +249,10 @@ public class ImageMagickControllerTest extends AbstractTransformerControllerTest .param("resizePercentage", "true") .param("allowEnlargement", "true") .param("maintainAspectRatio", "true")) - - .andExpect(status().is(OK.value())) - .andExpect(content().bytes(expectedTargetFileBytes)) - .andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''quick."+targetExtension)); + .andExpect(status().is(OK.value())) + .andExpect(content().bytes(expectedTargetFileBytes)) + .andExpect(header().string("Content-Disposition", + "attachment; filename*= UTF-8''quick." + targetExtension)); } @Test @@ -245,7 +260,9 @@ public class ImageMagickControllerTest extends AbstractTransformerControllerTest { expectedOptions = "-auto-orient -gravity SouthEast -crop 123x456+90+12 +repage -resize 321x654>"; expectedSourceSuffix = "[2-3]"; - mockMvc.perform(MockMvcRequestBuilders.multipart("/transform") + mockMvc + .perform(MockMvcRequestBuilders + .multipart("/transform") .file(sourceFile) .param("targetExtension", targetExtension) @@ -268,10 +285,10 @@ public class ImageMagickControllerTest extends AbstractTransformerControllerTest .param("resizePercentage", "false") .param("allowEnlargement", "false") .param("maintainAspectRatio", "false")) - - .andExpect(status().is(OK.value())) - .andExpect(content().bytes(expectedTargetFileBytes)) - .andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''quick."+targetExtension)); + .andExpect(status().is(OK.value())) + .andExpect(content().bytes(expectedTargetFileBytes)) + .andExpect(header().string("Content-Disposition", + "attachment; filename*= UTF-8''quick." + targetExtension)); } @Test @@ -279,16 +296,19 @@ public class ImageMagickControllerTest extends AbstractTransformerControllerTest { // Example of why the commandOptions parameter is a bad idea. expectedOptions = "( horrible command / ); -resize 321x654>"; - mockMvc.perform(MockMvcRequestBuilders.multipart("/transform") + mockMvc + .perform(MockMvcRequestBuilders + .multipart("/transform") .file(sourceFile) .param("targetExtension", targetExtension) .param("thumbnail", "false") .param("resizeWidth", "321") .param("resizeHeight", "654") .param("commandOptions", "( horrible command / );")) - .andExpect(status().is(OK.value())) - .andExpect(content().bytes(expectedTargetFileBytes)) - .andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''quick."+targetExtension)); + .andExpect(status().is(OK.value())) + .andExpect(content().bytes(expectedTargetFileBytes)) + .andExpect(header().string("Content-Disposition", + "attachment; filename*= UTF-8''quick." + targetExtension)); } @Override @@ -296,10 +316,10 @@ public class ImageMagickControllerTest extends AbstractTransformerControllerTest { transformRequest.setSourceExtension("png"); transformRequest.setTargetExtension("png"); - transformRequest.setSourceMediaType(MediaType.IMAGE_PNG_VALUE); - transformRequest.setTargetMediaType(MediaType.IMAGE_PNG_VALUE); + transformRequest.setSourceMediaType(IMAGE_PNG_VALUE); + transformRequest.setTargetMediaType(IMAGE_PNG_VALUE); } - + @Test public void badExitCodeTest() throws Exception { @@ -307,7 +327,8 @@ public class ImageMagickControllerTest extends AbstractTransformerControllerTest mockMvc.perform(mockMvcRequest("/transform", sourceFile, "targetExtension", "xxx")) .andExpect(status().is(BAD_REQUEST.value())) - .andExpect(status().reason(containsString("Transformer exit code was not 0: \nSTDERR"))); + .andExpect( + status().reason(containsString("Transformer exit code was not 0: \nSTDERR"))); } @Test @@ -318,7 +339,6 @@ public class ImageMagickControllerTest extends AbstractTransformerControllerTest File sourceFile = getTestFile("quick." + sourceExtension, true); String targetFileRef = UUID.randomUUID().toString(); - // Transformation Request POJO TransformRequest transformRequest = new TransformRequest(); transformRequest.setRequestId("1"); @@ -332,12 +352,13 @@ public class ImageMagickControllerTest extends AbstractTransformerControllerTest // HTTP Request HttpHeaders headers = new HttpHeaders(); - headers.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=quick." + sourceExtension); + headers.set(CONTENT_DISPOSITION, "attachment; filename=quick." + sourceExtension); ResponseEntity response = new ResponseEntity<>(new FileSystemResource( sourceFile), headers, OK); when(alfrescoSharedFileStoreClient.retrieveFile(sourceFileRef)).thenReturn(response); - when(alfrescoSharedFileStoreClient.saveFile(any())).thenReturn(new FileRefResponse(new FileRefEntity(targetFileRef))); + when(alfrescoSharedFileStoreClient.saveFile(any())) + .thenReturn(new FileRefResponse(new FileRefEntity(targetFileRef))); when(mockExecutionResult.getExitValue()).thenReturn(0); // Update the Transformation Request with any specific params before sending it @@ -345,18 +366,21 @@ public class ImageMagickControllerTest extends AbstractTransformerControllerTest // Serialize and call the transformer String tr = objectMapper.writeValueAsString(transformRequest); - String transformationReplyAsString = mockMvc.perform(MockMvcRequestBuilders.post("/transform") - .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).content(tr)) - .andExpect(status().is(HttpStatus.CREATED.value())) - .andReturn().getResponse().getContentAsString(); + String transformationReplyAsString = mockMvc + .perform(MockMvcRequestBuilders + .post("/transform") + .header(ACCEPT, APPLICATION_JSON_VALUE) + .header(CONTENT_TYPE, APPLICATION_JSON_VALUE) + .content(tr)) + .andExpect(status().is(CREATED.value())) + .andReturn().getResponse().getContentAsString(); - TransformReply transformReply = objectMapper.readValue(transformationReplyAsString, TransformReply.class); + TransformReply transformReply = objectMapper.readValue(transformationReplyAsString, + TransformReply.class); // Assert the reply assertEquals(transformRequest.getRequestId(), transformReply.getRequestId()); assertEquals(transformRequest.getClientData(), transformReply.getClientData()); assertEquals(transformRequest.getSchema(), transformReply.getSchema()); } - } diff --git a/alfresco-docker-imagemagick/src/test/java/org/alfresco/transformer/ImageMagickQueueTransformServiceIT.java b/alfresco-docker-imagemagick/src/test/java/org/alfresco/transformer/ImageMagickQueueTransformServiceIT.java index 412d2bd0..a6a74961 100644 --- a/alfresco-docker-imagemagick/src/test/java/org/alfresco/transformer/ImageMagickQueueTransformServiceIT.java +++ b/alfresco-docker-imagemagick/src/test/java/org/alfresco/transformer/ImageMagickQueueTransformServiceIT.java @@ -48,7 +48,8 @@ public class ImageMagickQueueTransformServiceIT extends AbstractQueueTransformSe @Override protected TransformRequest buildRequest() { - return TransformRequest.builder() + return TransformRequest + .builder() .withRequestId(UUID.randomUUID().toString()) .withSourceMediaType(MIMETYPE_IMAGE_PNG) .withTargetMediaType(MIMETYPE_IMAGE_JPEG) @@ -56,6 +57,7 @@ public class ImageMagickQueueTransformServiceIT extends AbstractQueueTransformSe .withSchema(1) .withClientData("ACS") .withSourceReference(UUID.randomUUID().toString()) - .withSourceSize(32L).build(); + .withSourceSize(32L) + .build(); } } diff --git a/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/Application.java b/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/Application.java index ecc5b58c..f189f571 100644 --- a/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/Application.java +++ b/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/Application.java @@ -26,30 +26,52 @@ */ package org.alfresco.transformer; -import io.micrometer.core.instrument.MeterRegistry; +import static org.alfresco.transformer.logging.StandardMessages.LICENCE; +import java.util.Arrays; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.annotation.Bean; +import org.springframework.context.event.EventListener; + +import io.micrometer.core.instrument.MeterRegistry; @SpringBootApplication -@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) +@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class}) public class Application { + private static final Logger logger = LoggerFactory.getLogger(Application.class); + @Value("${container.name}") private String containerName; @Bean - MeterRegistryCustomizer metricsCommonTags() { + MeterRegistryCustomizer metricsCommonTags() + { return registry -> registry.config().commonTags("containerName", containerName); } - + public static void main(String[] args) { SpringApplication.run(Application.class, args); } + + @EventListener(ApplicationReadyEvent.class) + public void startup() + { + logger.info("-------------------------------------------------------------------------------------------------------------------------------------------------------"); + Arrays.stream(LICENCE.split("\\n")).forEach(logger::info); + logger.info("This transformer uses LibreOffice from The Document Foundation. See the license at https://www.libreoffice.org/download/license/ or in /libreoffice.txt"); + logger.info("-------------------------------------------------------------------------------------------------------------------------------------------------------"); + + logger.info("Starting application components... Done"); + } } diff --git a/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/LibreOfficeController.java b/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/LibreOfficeController.java index cad84b4b..1f0ebd3e 100644 --- a/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/LibreOfficeController.java +++ b/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/LibreOfficeController.java @@ -30,11 +30,10 @@ import static org.alfresco.transformer.fs.FileManager.createAttachment; import static org.alfresco.transformer.fs.FileManager.createSourceFile; import static org.alfresco.transformer.fs.FileManager.createTargetFile; import static org.alfresco.transformer.fs.FileManager.createTargetFileName; -import static org.alfresco.transformer.logging.StandardMessages.LICENCE; import static org.springframework.http.HttpStatus.OK; +import static org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE; import java.io.File; -import java.util.Arrays; import java.util.Map; import javax.servlet.http.HttpServletRequest; @@ -46,7 +45,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; @@ -59,20 +57,20 @@ import org.springframework.web.multipart.MultipartFile; * * Status Codes: * - * 200 Success - * 400 Bad Request: Request parameter is missing (missing mandatory parameter) - * 400 Bad Request: Request parameter is of the wrong type - * 400 Bad Request: Transformer exit code was not 0 (possible problem with the source file) - * 400 Bad Request: The source filename was not supplied - * 500 Internal Server Error: (no message with low level IO problems) - * 500 Internal Server Error: The target filename was not supplied (should not happen as targetExtension is checked) - * 500 Internal Server Error: Transformer version check exit code was not 0 - * 500 Internal Server Error: Transformer version check failed to create any output - * 500 Internal Server Error: Could not read the target file - * 500 Internal Server Error: The target filename was malformed (should not happen because of other checks) - * 500 Internal Server Error: Transformer failed to create an output file (the exit code was 0, so there should be some content) - * 500 Internal Server Error: Filename encoding error - * 507 Insufficient Storage: Failed to store the source file + * 200 Success + * 400 Bad Request: Request parameter is missing (missing mandatory parameter) + * 400 Bad Request: Request parameter is of the wrong type + * 400 Bad Request: Transformer exit code was not 0 (possible problem with the source file) + * 400 Bad Request: The source filename was not supplied + * 500 Internal Server Error: (no message with low level IO problems) + * 500 Internal Server Error: The target filename was not supplied (should not happen as targetExtension is checked) + * 500 Internal Server Error: Transformer version check exit code was not 0 + * 500 Internal Server Error: Transformer version check failed to create any output + * 500 Internal Server Error: Could not read the target file + * 500 Internal Server Error: The target filename was malformed (should not happen because of other checks) + * 500 Internal Server Error: Transformer failed to create an output file (the exit code was 0, so there should be some content) + * 500 Internal Server Error: Filename encoding error + * 507 Insufficient Storage: Failed to store the source file */ @Controller public class LibreOfficeController extends AbstractTransformerController @@ -81,15 +79,6 @@ public class LibreOfficeController extends AbstractTransformerController @Autowired private LibreOfficeJavaExecutor javaExecutor; - - @Autowired - public LibreOfficeController() - { - logger.info("-------------------------------------------------------------------------------------------------------------------------------------------------------"); - Arrays.stream(LICENCE.split("\\n")).forEach(logger::info); - logger.info("This transformer uses LibreOffice from The Document Foundation. See the license at https://www.libreoffice.org/download/license/ or in /libreoffice.txt"); - logger.info("-------------------------------------------------------------------------------------------------------------------------------------------------------"); - } @Override public String getTransformerName() @@ -108,7 +97,7 @@ public class LibreOfficeController extends AbstractTransformerController { // See the Javadoc on this method and Probes.md for the choice of these values. return new ProbeTestTransform(this, "quick.doc", "quick.pdf", - 11817, 1024, 150, 10240, 60*30+1, 60*15+20) + 11817, 1024, 150, 10240, 60 * 30 + 1, 60 * 15 + 20) { @Override protected void executeTransformCommand(File sourceFile, File targetFile) @@ -119,14 +108,15 @@ public class LibreOfficeController extends AbstractTransformerController } //todo: the "timeout" request parameter is ignored; the timeout is preset at JodConverter creation - @PostMapping(value = "/transform", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @PostMapping(value = "/transform", consumes = MULTIPART_FORM_DATA_VALUE) public ResponseEntity transform(HttpServletRequest request, - @RequestParam("file") MultipartFile sourceMultipartFile, - @RequestParam("targetExtension") String targetExtension, - @RequestParam(value = "timeout", required = false) Long timeout, - @RequestParam(value = "testDelay", required = false) Long testDelay) + @RequestParam("file") MultipartFile sourceMultipartFile, + @RequestParam("targetExtension") String targetExtension, + @RequestParam(value = "timeout", required = false) Long timeout, + @RequestParam(value = "testDelay", required = false) Long testDelay) { - String targetFilename = createTargetFileName(sourceMultipartFile.getOriginalFilename(), targetExtension); + String targetFilename = createTargetFileName(sourceMultipartFile.getOriginalFilename(), + targetExtension); getProbeTestTransform().incrementTransformerCount(); File sourceFile = createSourceFile(request, sourceMultipartFile); File targetFile = createTargetFile(request, targetFilename); diff --git a/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/executors/JodConverter.java b/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/executors/JodConverter.java index 7cad6ea5..c9623cb0 100644 --- a/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/executors/JodConverter.java +++ b/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/executors/JodConverter.java @@ -34,12 +34,14 @@ public interface JodConverter { /** * Gets the JodConverter OfficeManager. + * * @return */ OfficeManager getOfficeManager(); /** * This method returns a boolean indicating whether the JodConverter connection to OOo is available. + * * @return true if available, else false */ boolean isAvailable(); diff --git a/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/executors/JodConverterSharedInstance.java b/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/executors/JodConverterSharedInstance.java index 1b4c8ff7..d4f44fcc 100644 --- a/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/executors/JodConverterSharedInstance.java +++ b/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/executors/JodConverterSharedInstance.java @@ -128,7 +128,7 @@ public class JodConverterSharedInstance implements JodConverter StringTokenizer tokenizer = new StringTokenizer(s, ","); int tokenCount = tokenizer.countTokens(); portNumbers = new int[tokenCount]; - for (int i = 0;tokenizer.hasMoreTokens();i++) + for (int i = 0; tokenizer.hasMoreTokens(); i++) { try { @@ -163,7 +163,8 @@ public class JodConverterSharedInstance implements JodConverter File tmp = new File(templateProfileDir); if (!tmp.isDirectory()) { - throw new AlfrescoRuntimeException("OpenOffice template profile directory "+templateProfileDir+" does not exist."); + throw new AlfrescoRuntimeException( + "OpenOffice template profile directory " + templateProfileDir + " does not exist."); } this.templateProfileDir = tmp; } @@ -176,7 +177,7 @@ public class JodConverterSharedInstance implements JodConverter void setConnectTimeout(String connectTimeout) { - this.connectTimeout = parseStringForLong(connectTimeout.trim()); + this.connectTimeout = parseStringForLong(connectTimeout.trim()); } void setEnabled(final String enabledStr) @@ -254,8 +255,8 @@ public class JodConverterSharedInstance implements JodConverter private int[] getPortNumbers() { return (enabled == null || !enabled) && deprecatedOooEnabled != null && deprecatedOooEnabled - ? deprecatedOooPortNumbers - : portNumbers; + ? deprecatedOooPortNumbers + : portNumbers; } private Long parseStringForLong(String string) @@ -287,14 +288,15 @@ public class JodConverterSharedInstance implements JodConverter @PostConstruct public void afterPropertiesSet() { - // isAvailable defaults to false afterPropertiesSet. It only becomes true on successful completion of this method. - this.isAvailable = false; + // isAvailable defaults to false afterPropertiesSet. It only becomes true on successful completion of this method. + this.isAvailable = false; int[] portNumbers = getPortNumbers(); String officeHome = getOfficeHome(); if (logger.isDebugEnabled()) { - logger.debug("JodConverter settings (null settings will be replaced by jodconverter defaults):"); + logger.debug( + "JodConverter settings (null settings will be replaced by jodconverter defaults):"); logger.debug(" officeHome = {}", officeHome); logger.debug(" enabled = {}", isEnabled()); logger.debug(" portNumbers = {}", getString(portNumbers)); @@ -390,7 +392,7 @@ public class JodConverterSharedInstance implements JodConverter StringBuilder portInfo = new StringBuilder(); if (portNumbers != null) { - for (int i = 0;i < portNumbers.length;i++) + for (int i = 0; i < portNumbers.length; i++) { portInfo.append(portNumbers[i]); if (i < portNumbers.length - 1) @@ -404,78 +406,77 @@ public class JodConverterSharedInstance implements JodConverter private void logAllSofficeFilesUnderOfficeHome() { - if (!logger.isDebugEnabled()) - { - return; - } + if (!logger.isDebugEnabled()) + { + return; + } - String officeHome = getOfficeHome(); - File requestedOfficeHome = new File(officeHome); + String officeHome = getOfficeHome(); + File requestedOfficeHome = new File(officeHome); - logger.debug("Some information on soffice* files and their permissions"); + logger.debug("Some information on soffice* files and their permissions"); - logFileInfo(requestedOfficeHome); + logFileInfo(requestedOfficeHome); - for (File f : findSofficePrograms(requestedOfficeHome, new ArrayList<>(), 2)) - { - logFileInfo(f); - } - } - - private List findSofficePrograms(File searchRoot, List results, int maxRecursionDepth) - { - return this.findSofficePrograms(searchRoot, results, 0, maxRecursionDepth); + for (File f : findSofficePrograms(requestedOfficeHome, new ArrayList<>(), 2)) + { + logFileInfo(f); + } } private List findSofficePrograms(File searchRoot, List results, - int currentRecursionDepth, int maxRecursionDepth) + int maxRecursionDepth) { - if (currentRecursionDepth >= maxRecursionDepth) - { - return results; - } + return this.findSofficePrograms(searchRoot, results, 0, maxRecursionDepth); + } - File[] matchingFiles = searchRoot.listFiles((dir, name) -> name.startsWith("soffice")); + private List findSofficePrograms(File searchRoot, List results, + int currentRecursionDepth, int maxRecursionDepth) + { + if (currentRecursionDepth >= maxRecursionDepth) + { + return results; + } + + File[] matchingFiles = searchRoot.listFiles((dir, name) -> name.startsWith("soffice")); results.addAll(asList(matchingFiles)); for (File dir : requireNonNull(searchRoot.listFiles(File::isDirectory))) - { - findSofficePrograms(dir, results, currentRecursionDepth + 1, maxRecursionDepth); - } + { + findSofficePrograms(dir, results, currentRecursionDepth + 1, maxRecursionDepth); + } - return results; + return results; } /** * Logs some information on the specified file, including name and r/w/x permissions. + * * @param f the file to log. */ private void logFileInfo(File f) { - if (!logger.isDebugEnabled()) - { - return; - } + if (!logger.isDebugEnabled()) + { + return; + } - StringBuilder msg = new StringBuilder(); - msg.append(f).append(" "); - if (f.exists()) - { - if (f.canRead()) - { - msg.append("(") - .append(f.isDirectory() ? "d" : "-") - .append(f.canRead() ? "r" : "-") - .append(f.canWrite() ? "w" : "-") - .append(f.canExecute() ? "x" : "-") - .append(")"); - } - } - else - { - msg.append("does not exist"); - } - logger.debug(msg.toString()); + StringBuilder msg = new StringBuilder(); + msg.append(f).append(" "); + if (f.exists() && f.canRead()) + { + msg.append("(") + .append(f.isDirectory() ? "d" : "-") + .append(f.canRead() ? "r" : "-") + .append(f.canWrite() ? "w" : "-") + .append(f.canExecute() ? "x" : "-") + .append(")"); + } + else + { + msg.append("does not exist"); + } + logger.debug(msg.toString()); } /* @@ -485,19 +486,19 @@ public class JodConverterSharedInstance implements JodConverter @PreDestroy public void destroy() { - this.isAvailable = false; - if (officeManager != null) - { - // If there is an OfficeException when stopping the officeManager below, then there is - // little that can be done other than logging the exception and carrying on. The JodConverter-based - // libraries will not be used in any case, as isAvailable is false. - // - // Any exception thrown out of this method will be logged and swallowed by Spring - // (see javadoc for method declaration). Therefore there is no handling here for - // exceptions from jodConverter. - officeManager.stop(); - } - } + this.isAvailable = false; + if (officeManager != null) + { + // If there is an OfficeException when stopping the officeManager below, then there is + // little that can be done other than logging the exception and carrying on. The JodConverter-based + // libraries will not be used in any case, as isAvailable is false. + // + // Any exception thrown out of this method will be logged and swallowed by Spring + // (see javadoc for method declaration). Therefore there is no handling here for + // exceptions from jodConverter. + officeManager.stop(); + } + } /* (non-Javadoc) * @see org.alfresco.repo.content.JodConverterWorker#getOfficeManager() diff --git a/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/executors/LibreOfficeJavaExecutor.java b/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/executors/LibreOfficeJavaExecutor.java index 77469bd3..d6a366e2 100644 --- a/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/executors/LibreOfficeJavaExecutor.java +++ b/alfresco-docker-libreoffice/src/main/java/org/alfresco/transformer/executors/LibreOfficeJavaExecutor.java @@ -35,20 +35,20 @@ import java.io.IOException; import javax.annotation.PostConstruct; import org.alfresco.transform.exceptions.TransformException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.artofsolving.jodconverter.OfficeDocumentConverter; import org.artofsolving.jodconverter.office.OfficeException; import org.artofsolving.jodconverter.office.OfficeManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import com.sun.star.task.ErrorCodeIOException; /** - * JavaExecutor implementation for running LibreOffice transformations. It loads the + * JavaExecutor implementation for running LibreOffice transformations. It loads the * transformation logic in the same JVM (check the {@link JodConverter} implementation). */ @Component diff --git a/alfresco-docker-libreoffice/src/test/java/org/alfresco/transformer/LibreOfficeControllerTest.java b/alfresco-docker-libreoffice/src/test/java/org/alfresco/transformer/LibreOfficeControllerTest.java index 571f17a9..d6bc3827 100644 --- a/alfresco-docker-libreoffice/src/test/java/org/alfresco/transformer/LibreOfficeControllerTest.java +++ b/alfresco-docker-libreoffice/src/test/java/org/alfresco/transformer/LibreOfficeControllerTest.java @@ -34,7 +34,15 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.when; +import static org.springframework.http.HttpHeaders.ACCEPT; +import static org.springframework.http.HttpHeaders.CONTENT_DISPOSITION; +import static org.springframework.http.HttpHeaders.CONTENT_TYPE; +import static org.springframework.http.HttpStatus.CREATED; +import static org.springframework.http.HttpStatus.OK; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; +import static org.springframework.http.MediaType.IMAGE_PNG_VALUE; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.util.StringUtils.getFilenameExtension; import java.io.File; import java.io.IOException; @@ -59,13 +67,10 @@ import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.mock.web.MockMultipartFile; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -import org.springframework.util.StringUtils; /** * Test the LibreOfficeController without a server. @@ -94,15 +99,18 @@ public class LibreOfficeControllerTest extends AbstractTransformerControllerTest // The following is based on super.mockTransformCommand(...) // This is because LibreOffice used JodConverter rather than a RuntimeExec - expectedSourceFileBytes = Files.readAllBytes(getTestFile("quick." + sourceExtension, true).toPath()); - expectedTargetFileBytes = Files.readAllBytes(getTestFile("quick." + targetExtension, true).toPath()); - sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype, expectedSourceFileBytes); + expectedSourceFileBytes = Files.readAllBytes( + getTestFile("quick." + sourceExtension, true).toPath()); + expectedTargetFileBytes = Files.readAllBytes( + getTestFile("quick." + targetExtension, true).toPath()); + sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype, + expectedSourceFileBytes); doAnswer(invocation -> { File sourceFile = invocation.getArgument(0); File targetFile = invocation.getArgument(1); - String actualTargetExtension = StringUtils.getFilenameExtension(targetFile.getAbsolutePath()); + String actualTargetExtension = getFilenameExtension(targetFile.getAbsolutePath()); assertNotNull(sourceFile); assertNotNull(targetFile); @@ -119,7 +127,8 @@ public class LibreOfficeControllerTest extends AbstractTransformerControllerTest // Check the supplied source file has not been changed. byte[] actualSourceFileBytes = Files.readAllBytes(sourceFile.toPath()); - assertTrue("Source file is not the same", Arrays.equals(expectedSourceFileBytes, actualSourceFileBytes)); + assertTrue("Source file is not the same", + Arrays.equals(expectedSourceFileBytes, actualSourceFileBytes)); return null; }).when(javaExecutor).convert(any(), any()); @@ -143,11 +152,14 @@ public class LibreOfficeControllerTest extends AbstractTransformerControllerTest { doThrow(OfficeException.class).when(javaExecutor).convert(any(), any()); - mockMvc.perform(MockMvcRequestBuilders.multipart("/transform") - .file(sourceFile) - .param("targetExtension", "xxx")) - .andExpect(status().is(400)) - .andExpect(status().reason(containsString("LibreOffice - LibreOffice server conversion failed:"))); + mockMvc + .perform(MockMvcRequestBuilders + .multipart("/transform") + .file(sourceFile) + .param("targetExtension", "xxx")) + .andExpect(status().is(400)) + .andExpect(status().reason( + containsString("LibreOffice - LibreOffice server conversion failed:"))); } @Override @@ -156,7 +168,7 @@ public class LibreOfficeControllerTest extends AbstractTransformerControllerTest transformRequest.setSourceExtension("doc"); transformRequest.setTargetExtension("pdf"); transformRequest.setSourceMediaType("application/msword"); - transformRequest.setTargetMediaType(MediaType.IMAGE_PNG_VALUE); + transformRequest.setTargetMediaType(IMAGE_PNG_VALUE); } @Test @@ -180,14 +192,13 @@ public class LibreOfficeControllerTest extends AbstractTransformerControllerTest // HTTP Request HttpHeaders headers = new HttpHeaders(); - headers.set(HttpHeaders.CONTENT_DISPOSITION, - "attachment; filename=quick." + sourceExtension); + headers.set(CONTENT_DISPOSITION, "attachment; filename=quick." + sourceExtension); ResponseEntity response = new ResponseEntity<>(new FileSystemResource( - sourceFile), headers, HttpStatus.OK); + sourceFile), headers, OK); when(alfrescoSharedFileStoreClient.retrieveFile(sourceFileRef)).thenReturn(response); - when(alfrescoSharedFileStoreClient.saveFile(any())).thenReturn( - new FileRefResponse(new FileRefEntity(targetFileRef))); + when(alfrescoSharedFileStoreClient.saveFile(any())) + .thenReturn(new FileRefResponse(new FileRefEntity(targetFileRef))); when(mockExecutionResult.getExitValue()).thenReturn(0); // Update the Transformation Request with any specific params before sending it @@ -195,14 +206,14 @@ public class LibreOfficeControllerTest extends AbstractTransformerControllerTest // Serialize and call the transformer String tr = objectMapper.writeValueAsString(transformRequest); - String transformationReplyAsString = mockMvc.perform( - MockMvcRequestBuilders.post("/transform") - .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) - .header(HttpHeaders.CONTENT_TYPE, - MediaType.APPLICATION_JSON_VALUE).content(tr)) - .andExpect( - status().is(HttpStatus.CREATED.value())) - .andReturn().getResponse().getContentAsString(); + String transformationReplyAsString = mockMvc + .perform(MockMvcRequestBuilders + .post("/transform") + .header(ACCEPT, APPLICATION_JSON_VALUE) + .header(CONTENT_TYPE, APPLICATION_JSON_VALUE) + .content(tr)) + .andExpect(status().is(CREATED.value())) + .andReturn().getResponse().getContentAsString(); TransformReply transformReply = objectMapper.readValue(transformationReplyAsString, TransformReply.class); diff --git a/alfresco-docker-libreoffice/src/test/java/org/alfresco/transformer/LibreOfficeQueueTransformServiceIT.java b/alfresco-docker-libreoffice/src/test/java/org/alfresco/transformer/LibreOfficeQueueTransformServiceIT.java index 5437fd17..2e1f4d7e 100644 --- a/alfresco-docker-libreoffice/src/test/java/org/alfresco/transformer/LibreOfficeQueueTransformServiceIT.java +++ b/alfresco-docker-libreoffice/src/test/java/org/alfresco/transformer/LibreOfficeQueueTransformServiceIT.java @@ -47,7 +47,8 @@ public class LibreOfficeQueueTransformServiceIT extends AbstractQueueTransformSe @Override protected TransformRequest buildRequest() { - return TransformRequest.builder() + return TransformRequest + .builder() .withRequestId(UUID.randomUUID().toString()) .withSourceMediaType(MIMETYPE_OPENXML_WORDPROCESSING) .withTargetMediaType(MIMETYPE_OPENXML_WORDPROCESSING) @@ -55,6 +56,7 @@ public class LibreOfficeQueueTransformServiceIT extends AbstractQueueTransformSe .withSchema(1) .withClientData("ACS") .withSourceReference(UUID.randomUUID().toString()) - .withSourceSize(32L).build(); + .withSourceSize(32L) + .build(); } } diff --git a/alfresco-docker-tika/src/main/java/org/alfresco/transformer/Application.java b/alfresco-docker-tika/src/main/java/org/alfresco/transformer/Application.java index 62c18554..731f46c1 100644 --- a/alfresco-docker-tika/src/main/java/org/alfresco/transformer/Application.java +++ b/alfresco-docker-tika/src/main/java/org/alfresco/transformer/Application.java @@ -26,20 +26,30 @@ */ package org.alfresco.transformer; +import static org.alfresco.transformer.logging.StandardMessages.LICENCE; + +import java.util.Arrays; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.annotation.Bean; +import org.springframework.context.event.EventListener; import io.micrometer.core.instrument.MeterRegistry; @SpringBootApplication -@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) +@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class}) public class Application { + private static final Logger logger = LoggerFactory.getLogger(Application.class); + @Value("${container.name}") private String containerName; @@ -53,4 +63,15 @@ public class Application { SpringApplication.run(Application.class, args); } + + @EventListener(ApplicationReadyEvent.class) + public void startup() + { + logger.info("--------------------------------------------------------------------------------------------------------------------------------------------------------------"); + Arrays.stream(LICENCE.split("\\n")).forEach(logger::info); + logger.info("Tika is from Apache. See the license at http://www.apache.org/licenses/LICENSE-2.0. or in /Apache\\ 2.0.txt"); + logger.info("--------------------------------------------------------------------------------------------------------------------------------------------------------------"); + + logger.info("Starting application components... Done"); + } } diff --git a/alfresco-docker-tika/src/main/java/org/alfresco/transformer/TikaController.java b/alfresco-docker-tika/src/main/java/org/alfresco/transformer/TikaController.java index 32e0528f..dcf0393e 100644 --- a/alfresco-docker-tika/src/main/java/org/alfresco/transformer/TikaController.java +++ b/alfresco-docker-tika/src/main/java/org/alfresco/transformer/TikaController.java @@ -37,13 +37,12 @@ import static org.alfresco.transformer.fs.FileManager.createAttachment; import static org.alfresco.transformer.fs.FileManager.createSourceFile; import static org.alfresco.transformer.fs.FileManager.createTargetFile; import static org.alfresco.transformer.fs.FileManager.createTargetFileName; -import static org.alfresco.transformer.logging.StandardMessages.LICENCE; import static org.alfresco.transformer.util.Util.stringToBoolean; import static org.springframework.http.HttpStatus.BAD_REQUEST; import static org.springframework.http.HttpStatus.OK; +import static org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE; import java.io.File; -import java.util.Arrays; import java.util.Map; import javax.servlet.http.HttpServletRequest; @@ -56,7 +55,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; @@ -69,9 +67,9 @@ import org.springframework.web.multipart.MultipartFile; * Status Codes: * * 200 Success - * 400 Bad Request: Invalid target mimetype <mimetype> - * 400 Bad Request: Request parameter <name> is missing (missing mandatory parameter) - * 400 Bad Request: Request parameter <name> is of the wrong type + * 400 Bad Request: Invalid target mimetype + * 400 Bad Request: Request parameter is missing (missing mandatory parameter) + * 400 Bad Request: Request parameter is of the wrong type * 400 Bad Request: Transformer exit code was not 0 (possible problem with the source file) * 400 Bad Request: The source filename was not supplied * 500 Internal Server Error: (no message with low level IO problems) @@ -92,15 +90,6 @@ public class TikaController extends AbstractTransformerController @Autowired private TikaJavaExecutor javaExecutor; - @Autowired - public TikaController() - { - logger.info("--------------------------------------------------------------------------------------------------------------------------------------------------------------"); - Arrays.stream(LICENCE.split("\\n")).forEach(logger::info); - logger.info("Tika is from Apache. See the license at http://www.apache.org/licenses/LICENSE-2.0. or in /Apache\\ 2.0.txt"); - logger.info("--------------------------------------------------------------------------------------------------------------------------------------------------------------"); - } - @Override public String getTransformerName() { @@ -130,7 +119,7 @@ public class TikaController extends AbstractTransformerController }; } - @PostMapping(value = "/transform", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @PostMapping(value = "/transform", consumes = MULTIPART_FORM_DATA_VALUE) public ResponseEntity transform(HttpServletRequest request, @RequestParam("file") MultipartFile sourceMultipartFile, @RequestParam("targetExtension") String targetExtension, @@ -149,7 +138,8 @@ public class TikaController extends AbstractTransformerController throw new TransformException(BAD_REQUEST.value(), "Invalid transform value"); } - String targetFilename = createTargetFileName(sourceMultipartFile.getOriginalFilename(), targetExtension); + String targetFilename = createTargetFileName(sourceMultipartFile.getOriginalFilename(), + targetExtension); getProbeTestTransform().incrementTransformerCount(); File sourceFile = createSourceFile(request, sourceMultipartFile); File targetFile = createTargetFile(request, targetFilename); diff --git a/alfresco-docker-tika/src/main/java/org/alfresco/transformer/executors/Tika.java b/alfresco-docker-tika/src/main/java/org/alfresco/transformer/executors/Tika.java index 4076d77d..9ea1b3de 100644 --- a/alfresco-docker-tika/src/main/java/org/alfresco/transformer/executors/Tika.java +++ b/alfresco-docker-tika/src/main/java/org/alfresco/transformer/executors/Tika.java @@ -26,7 +26,6 @@ */ package org.alfresco.transformer.executors; -import static java.util.Arrays.asList; import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_HTML; import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_IMAGE_JPEG; import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_IMAGE_PNG; @@ -74,6 +73,8 @@ import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; +import com.google.common.collect.ImmutableList; + /** * Stripped down command line Tika transformers. Not actually run as a separate process, but the code fits the patten * used by transformers that do. @@ -455,26 +456,26 @@ public class Tika public static final String TIKA_AUTO = "TikaAuto"; public static final String TEXT_MINING = "TextMining"; - public static final List TRANSFORM_NAMES = asList( - ARCHIVE, OUTLOOK_MSG, PDF_BOX, POI_OFFICE, POI, POI_OO_XML, TIKA_AUTO, TEXT_MINING); + public static final List TRANSFORM_NAMES = ImmutableList.of( + ARCHIVE, OUTLOOK_MSG, PDF_BOX, POI_OFFICE, POI, POI_OO_XML, TIKA_AUTO, TEXT_MINING); public static final String TARGET_MIMETYPE = "--targetMimetype="; public static final String TARGET_ENCODING = "--targetEncoding="; public static final String INCLUDE_CONTENTS = "--includeContents"; public static final String NOT_EXTRACT_BOOKMARKS_TEXT = "--notExtractBookmarksText"; - public static final String CSV = "csv"; - public static final String DOC = "doc"; - public static final String DOCX = "docx"; - public static final String HTML = "html"; - public static final String MSG = "msg"; - public static final String PDF = "pdf"; - public static final String PPTX = "pptx"; - public static final String TXT = "txt"; - public static final String XHTML = "xhtml"; - public static final String XSLX = "xslx"; - public static final String XML = "xml"; - public static final String ZIP = "zip"; + public static final String CSV = "csv"; + public static final String DOC = "doc"; + public static final String DOCX = "docx"; + public static final String HTML = "html"; + public static final String MSG = "msg"; + public static final String PDF = "pdf"; + public static final String PPTX = "pptx"; + public static final String TXT = "txt"; + public static final String XHTML = "xhtml"; + public static final String XSLX = "xslx"; + public static final String XML = "xml"; + public static final String ZIP = "zip"; private final Parser packageParser = new PackageParser(); private final Parser pdfParser = new PDFParser(); @@ -484,9 +485,10 @@ public class Tika private final Parser tikaOfficeDetectParser = new TikaOfficeDetectParser(); private final PDFParserConfig pdfParserConfig = new PDFParserConfig(); - private DocumentSelector pdfBoxEmbededDocumentSelector = new DocumentSelector() + private final DocumentSelector pdfBoxEmbededDocumentSelector = new DocumentSelector() { - private final List disabledMediaTypes = asList(MIMETYPE_IMAGE_JPEG, MIMETYPE_IMAGE_TIFF, MIMETYPE_IMAGE_PNG); + private final List disabledMediaTypes = ImmutableList.of(MIMETYPE_IMAGE_JPEG, + MIMETYPE_IMAGE_TIFF, MIMETYPE_IMAGE_PNG); @Override public boolean select(Metadata metadata) @@ -518,16 +520,16 @@ public class Tika } catch (IllegalArgumentException e) { - System.err.println("ERROR "+e.getMessage()); + System.err.println("ERROR " + e.getMessage()); System.exit(-1); } catch (IllegalStateException | TikaException | IOException | SAXException e) { - System.err.println("ERROR "+e.getMessage()); + System.err.println("ERROR " + e.getMessage()); e.printStackTrace(); System.exit(-2); } - System.out.println("Finished in "+(System.currentTimeMillis()-start)+"ms"); + System.out.println("Finished in " + (System.currentTimeMillis() - start) + "ms"); } // Extracts parameters form args @@ -541,7 +543,7 @@ public class Tika Boolean includeContents = null; Boolean notExtractBookmarksText = null; - for (String arg: args) + for (String arg : args) { if (arg.startsWith("--")) { @@ -565,7 +567,7 @@ public class Tika } else { - throw new IllegalArgumentException("Unexpected argument "+arg); + throw new IllegalArgumentException("Unexpected argument " + arg); } } else @@ -584,7 +586,7 @@ public class Tika } else { - throw new IllegalArgumentException("Unexpected argument "+arg); + throw new IllegalArgumentException("Unexpected argument " + arg); } } } @@ -593,71 +595,73 @@ public class Tika throw new IllegalArgumentException("Missing arguments"); } includeContents = includeContents == null ? false : includeContents; - notExtractBookmarksText = notExtractBookmarksText == null ? false : notExtractBookmarksText; + notExtractBookmarksText = notExtractBookmarksText == null ? false : notExtractBookmarksText; - transform(transform, includeContents, notExtractBookmarksText, sourceFilename, targetFilename, targetMimetype, targetEncoding); + transform(transform, includeContents, notExtractBookmarksText, sourceFilename, + targetFilename, targetMimetype, targetEncoding); } private String getValue(String arg, boolean valueExpected, Object value, String optionName) { if (value != null) { - throw new IllegalArgumentException("Duplicate "+optionName); + throw new IllegalArgumentException("Duplicate " + optionName); } String stringValue = arg.substring(optionName.length()).trim(); if (!valueExpected && stringValue.length() > 0) { - throw new IllegalArgumentException("Unexpected value with "+optionName); + throw new IllegalArgumentException("Unexpected value with " + optionName); } if (valueExpected && stringValue.length() == 0) { - throw new IllegalArgumentException("Expected value with "+optionName); + throw new IllegalArgumentException("Expected value with " + optionName); } return stringValue; } // Adds transform specific values such as parser and documentSelector. private void transform(String transform, Boolean includeContents, - Boolean notExtractBookmarksText, - String sourceFilename, - String targetFilename, String targetMimetype, String targetEncoding) + Boolean notExtractBookmarksText, + String sourceFilename, + String targetFilename, String targetMimetype, String targetEncoding) { Parser parser = null; DocumentSelector documentSelector = null; - switch(transform) + switch (transform) { - case ARCHIVE: - parser = packageParser; - break; - case OUTLOOK_MSG: - case POI_OFFICE: - case TEXT_MINING: - parser = officeParser; - break; - case PDF_BOX: - parser = pdfParser; - documentSelector = pdfBoxEmbededDocumentSelector; - break; - case POI: - parser = tikaOfficeDetectParser; - break; - case POI_OO_XML: - parser = ooXmlParser; - break; - case TIKA_AUTO: - parser = autoDetectParser; - break; + case ARCHIVE: + parser = packageParser; + break; + case OUTLOOK_MSG: + case POI_OFFICE: + case TEXT_MINING: + parser = officeParser; + break; + case PDF_BOX: + parser = pdfParser; + documentSelector = pdfBoxEmbededDocumentSelector; + break; + case POI: + parser = tikaOfficeDetectParser; + break; + case POI_OO_XML: + parser = ooXmlParser; + break; + case TIKA_AUTO: + parser = autoDetectParser; + break; } - transform(parser, documentSelector, includeContents, notExtractBookmarksText, sourceFilename, targetFilename, targetMimetype, targetEncoding); + transform(parser, documentSelector, includeContents, notExtractBookmarksText, + sourceFilename, targetFilename, targetMimetype, targetEncoding); } - - private void transform(Parser parser, DocumentSelector documentSelector, Boolean includeContents, - Boolean notExtractBookmarksText, - String sourceFilename, - String targetFilename, String targetMimetype, String targetEncoding) + private void transform(Parser parser, DocumentSelector documentSelector, + Boolean includeContents, + Boolean notExtractBookmarksText, + String sourceFilename, + String targetFilename, String targetMimetype, String targetEncoding) { try (InputStream is = new BufferedInputStream(new FileInputStream(sourceFilename)); @@ -688,7 +692,7 @@ public class Tika } else { - SAXTransformerFactory factory = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); + SAXTransformerFactory factory = (SAXTransformerFactory) SAXTransformerFactory.newInstance(); TransformerHandler transformerHandler; transformerHandler = factory.newTransformerHandler(); transformerHandler.getTransformer().setOutputProperty(OutputKeys.INDENT, "yes"); @@ -725,42 +729,52 @@ public class Tika /** * A wrapper around the normal Tika BodyContentHandler for CSV rather encoding than tab separated. */ - protected static class CsvContentHandler extends BodyContentHandler { - private static final char[] comma = new char[]{ ',' }; + protected static class CsvContentHandler extends BodyContentHandler + { + private static final char[] comma = new char[]{','}; private static final Pattern all_nums = Pattern.compile("[\\d\\.\\-\\+]+"); private boolean inCell = false; private boolean needsComma = false; - protected CsvContentHandler(Writer output) { + protected CsvContentHandler(Writer output) + { super(output); } @Override public void ignorableWhitespace(char[] ch, int start, int length) - throws SAXException { - if(length == 1 && ch[0] == '\t') { + throws SAXException + { + if (length == 1 && ch[0] == '\t') + { // Ignore tabs, as they mess up the CSV output - } else { + } + else + { super.ignorableWhitespace(ch, start, length); } } @Override public void characters(char[] ch, int start, int length) - throws SAXException { - if(inCell) { - StringBuffer t = new StringBuffer(new String(ch,start,length)); + throws SAXException + { + if (inCell) + { + StringBuffer t = new StringBuffer(new String(ch, start, length)); // Quote if not all numbers - if(all_nums.matcher(t).matches()) + if (all_nums.matcher(t).matches()) { super.characters(ch, start, length); } else { - for(int i=t.length()-1; i>=0; i--) { - if(t.charAt(i) == '\"') { + for (int i = t.length() - 1; i >= 0; i--) + { + if (t.charAt(i) == '\"') + { // Double up double quotes t.insert(i, '\"'); i--; @@ -771,33 +785,45 @@ public class Tika char[] c = t.toString().toCharArray(); super.characters(c, 0, c.length); } - } else { + } + else + { super.characters(ch, start, length); } } @Override public void startElement(String uri, String localName, String name, - Attributes atts) throws SAXException { - if(localName.equals("td")) { + Attributes atts) throws SAXException + { + if (localName.equals("td")) + { inCell = true; - if(needsComma) { + if (needsComma) + { super.characters(comma, 0, 1); needsComma = true; } - } else { + } + else + { super.startElement(uri, localName, name, atts); } } @Override public void endElement(String uri, String localName, String name) - throws SAXException { - if(localName.equals("td")) { + throws SAXException + { + if (localName.equals("td")) + { needsComma = true; inCell = false; - } else { - if(localName.equals("tr")) { + } + else + { + if (localName.equals("tr")) + { needsComma = false; } super.endElement(uri, localName, name); @@ -830,5 +856,4 @@ public class Tika return context; } - } diff --git a/alfresco-docker-tika/src/main/java/org/alfresco/transformer/executors/TikaJavaExecutor.java b/alfresco-docker-tika/src/main/java/org/alfresco/transformer/executors/TikaJavaExecutor.java index dc81f5c0..9f73d2cb 100644 --- a/alfresco-docker-tika/src/main/java/org/alfresco/transformer/executors/TikaJavaExecutor.java +++ b/alfresco-docker-tika/src/main/java/org/alfresco/transformer/executors/TikaJavaExecutor.java @@ -42,7 +42,7 @@ import org.springframework.stereotype.Component; import org.xml.sax.SAXException; /** - * JavaExecutor implementation for running TIKA transformations. It loads the + * JavaExecutor implementation for running TIKA transformations. It loads the * transformation logic in the same JVM (check {@link Tika}). */ @Component diff --git a/alfresco-docker-tika/src/main/java/org/alfresco/transformer/executors/TikaOfficeDetectParser.java b/alfresco-docker-tika/src/main/java/org/alfresco/transformer/executors/TikaOfficeDetectParser.java index 321bcf0d..6600e472 100644 --- a/alfresco-docker-tika/src/main/java/org/alfresco/transformer/executors/TikaOfficeDetectParser.java +++ b/alfresco-docker-tika/src/main/java/org/alfresco/transformer/executors/TikaOfficeDetectParser.java @@ -48,21 +48,23 @@ import org.xml.sax.SAXException; /** * Apache Tika assumes that - * you either know exactly what your content is, or that - * you'll leave it to auto-detection. + * you either know exactly what your content is, or that + * you'll leave it to auto-detection. * Within Alfresco, we usually do know. However, from time - * to time, we don't know if we have one of the old or one - * of the new office files (eg .xls and .xlsx). + * to time, we don't know if we have one of the old or one + * of the new office files (eg .xls and .xlsx). * This class allows automatically selects the appropriate - * old (OLE2) or new (OOXML) Tika parser as required. + * old (OLE2) or new (OOXML) Tika parser as required. * * @author Nick Burch */ -public class TikaOfficeDetectParser implements Parser { +public class TikaOfficeDetectParser implements Parser +{ private final Parser ole2Parser = new OfficeParser(); private final Parser ooxmlParser = new OOXMLParser(); - public Set getSupportedTypes(ParseContext parseContext) { + public Set getSupportedTypes(ParseContext parseContext) + { Set types = new HashSet<>(); types.addAll(ole2Parser.getSupportedTypes(parseContext)); types.addAll(ooxmlParser.getSupportedTypes(parseContext)); @@ -70,9 +72,9 @@ public class TikaOfficeDetectParser implements Parser { } public void parse(InputStream stream, - ContentHandler handler, Metadata metadata, - ParseContext parseContext) throws IOException, SAXException, - TikaException + ContentHandler handler, Metadata metadata, + ParseContext parseContext) throws IOException, SAXException, + TikaException { byte[] initial4 = new byte[4]; InputStream wrapped; @@ -93,10 +95,10 @@ public class TikaOfficeDetectParser implements Parser { } // Which is it? - if(initial4[0] == POIFSConstants.OOXML_FILE_HEADER[0] && - initial4[1] == POIFSConstants.OOXML_FILE_HEADER[1] && - initial4[2] == POIFSConstants.OOXML_FILE_HEADER[2] && - initial4[3] == POIFSConstants.OOXML_FILE_HEADER[3]) + if (initial4[0] == POIFSConstants.OOXML_FILE_HEADER[0] && + initial4[1] == POIFSConstants.OOXML_FILE_HEADER[1] && + initial4[2] == POIFSConstants.OOXML_FILE_HEADER[2] && + initial4[3] == POIFSConstants.OOXML_FILE_HEADER[3]) { ooxmlParser.parse(wrapped, handler, metadata, parseContext); } @@ -110,8 +112,8 @@ public class TikaOfficeDetectParser implements Parser { * @deprecated This method will be removed in Apache Tika 1.0. */ public void parse(InputStream stream, - ContentHandler handler, Metadata metadata) - throws IOException, SAXException, TikaException + ContentHandler handler, Metadata metadata) + throws IOException, SAXException, TikaException { parse(stream, handler, metadata, new ParseContext()); } diff --git a/alfresco-docker-tika/src/test/java/org/alfresco/transformer/TikaControllerTest.java b/alfresco-docker-tika/src/test/java/org/alfresco/transformer/TikaControllerTest.java index 9b73f9e4..38a642d7 100644 --- a/alfresco-docker-tika/src/test/java/org/alfresco/transformer/TikaControllerTest.java +++ b/alfresco-docker-tika/src/test/java/org/alfresco/transformer/TikaControllerTest.java @@ -64,10 +64,18 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.when; +import static org.springframework.http.HttpHeaders.ACCEPT; +import static org.springframework.http.HttpHeaders.CONTENT_DISPOSITION; +import static org.springframework.http.HttpHeaders.CONTENT_TYPE; +import static org.springframework.http.HttpStatus.CREATED; import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; import static org.springframework.http.HttpStatus.OK; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; +import static org.springframework.http.MediaType.APPLICATION_PDF_VALUE; +import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.util.StringUtils.getFilenameExtension; import java.io.File; import java.io.IOException; @@ -93,15 +101,12 @@ import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.mock.web.MockMultipartFile; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -import org.springframework.util.StringUtils; /** * Test the TikaController without a server. @@ -112,7 +117,7 @@ import org.springframework.util.StringUtils; public class TikaControllerTest extends AbstractTransformerControllerTest { private static final String EXPECTED_XHTML_CONTENT_CONTAINS = "

The quick brown fox jumps over the lazy dog

"; - private static final String EXPECTED_TEXT_CONTENT_CONTAINS = "The quick brown fox jumps over the lazy dog"; + private static final String EXPECTED_TEXT_CONTENT_CONTAINS = "The quick brown fox jumps over the lazy dog"; private static final String EXPECTED_MSG_CONTENT_CONTAINS = "Recipients\n" + "\tmark.rogers@alfresco.com; speedy@quick.com; mrquick@nowhere.com\n" + "\n" + @@ -130,7 +135,7 @@ public class TikaControllerTest extends AbstractTransformerControllerTest @SpyBean private TikaJavaExecutor javaExecutor; - + @SpyBean private TikaController controller; @@ -169,7 +174,7 @@ public class TikaControllerTest extends AbstractTransformerControllerTest String actualOptions = actualProperties.get("options"); String actualSource = actualProperties.get("source"); String actualTarget = actualProperties.get("target"); - String actualTargetExtension = StringUtils.getFilenameExtension(actualTarget); + String actualTargetExtension = getFilenameExtension(actualTarget); assertNotNull(actualSource); assertNotNull(actualTarget); @@ -226,34 +231,39 @@ public class TikaControllerTest extends AbstractTransformerControllerTest } private void transform(String transform, String sourceExtension, String targetExtension, - String sourceMimetype, String targetMimetype, - Boolean includeContents, String expectedContentContains) throws Exception + String sourceMimetype, String targetMimetype, + Boolean includeContents, String expectedContentContains) throws Exception { // We don't use targetFileBytes as some of the transforms contain different date text based on the os being used. mockTransformCommand(sourceExtension, targetExtension, sourceMimetype, false); this.transform = transform; this.targetMimetype = targetMimetype; - System.out.println("Test "+transform+" "+ sourceExtension +" to "+targetExtension); + System.out.println("Test " + transform + " " + sourceExtension + " to " + targetExtension); MockHttpServletRequestBuilder requestBuilder = includeContents == null - ? mockMvcRequest("/transform", sourceFile, "targetExtension", this.targetExtension) - : mockMvcRequest("/transform", sourceFile, "targetExtension", this.targetExtension, "includeContents", includeContents.toString()); + ? mockMvcRequest("/transform", sourceFile, + "targetExtension", this.targetExtension) + : mockMvcRequest("/transform", sourceFile, + "targetExtension", this.targetExtension, "includeContents", includeContents.toString()); MvcResult result = mockMvc.perform(requestBuilder) - .andExpect(status().is(OK.value())) - .andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''quick." + this.targetExtension)). - andReturn(); + .andExpect(status().is(OK.value())) + .andExpect(header().string("Content-Disposition", + "attachment; filename*= UTF-8''quick." + this.targetExtension)). + andReturn(); String content = result.getResponse().getContentAsString(); - assertTrue("The content did not include \""+expectedContentContains, content.contains(expectedContentContains)); + assertTrue("The content did not include \"" + expectedContentContains, + content.contains(expectedContentContains)); } @Override // Add extra required parameters to the request. - protected MockHttpServletRequestBuilder mockMvcRequest(String url, MockMultipartFile sourceFile, String... params) + protected MockHttpServletRequestBuilder mockMvcRequest(String url, MockMultipartFile sourceFile, + String... params) { return super.mockMvcRequest(url, sourceFile, params) - .param("transform", transform) - .param("targetEncoding", targetEncoding) - .param("targetMimetype", targetMimetype); + .param("transform", transform) + .param("targetEncoding", targetEncoding) + .param("targetMimetype", targetMimetype); } @Test @@ -337,8 +347,9 @@ public class TikaControllerTest extends AbstractTransformerControllerTest { mockTransformCommand(PDF, TXT, MIMETYPE_PDF, true); targetEncoding = "rubbish"; - mockMvc.perform(mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension)) - .andExpect(status().is(INTERNAL_SERVER_ERROR.value())); + mockMvc.perform( + mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension)) + .andExpect(status().is(INTERNAL_SERVER_ERROR.value())); } // --- Archive --- @@ -346,56 +357,56 @@ public class TikaControllerTest extends AbstractTransformerControllerTest @Test public void zipToTextArchiveTest() throws Exception { - transform(ARCHIVE, ZIP, TXT, MIMETYPE_ZIP, MIMETYPE_TEXT_PLAIN,false, - "quick.html\n" + - "\n" + - "\n" + - "quick.pdf\n" + - "\n" + - "\n"); + transform(ARCHIVE, ZIP, TXT, MIMETYPE_ZIP, MIMETYPE_TEXT_PLAIN, false, + "quick.html\n" + + "\n" + + "\n" + + "quick.pdf\n" + + "\n" + + "\n"); } @Test public void zipToTextIncludeArchiveTest() throws Exception { - transform(ARCHIVE, ZIP, TXT, MIMETYPE_ZIP, MIMETYPE_TEXT_PLAIN,true, - "quick.html\n" + - "\n" + - "\n" + - "The quick brown fox jumps over the lazy dog\n" + - "\n" + - "\n" + - "\n" + - "quick.pdf\n" + - "\n" + - "\n" + - "The quick brown fox jumps over the lazy dog" + - "\n" + - "\n"); + transform(ARCHIVE, ZIP, TXT, MIMETYPE_ZIP, MIMETYPE_TEXT_PLAIN, true, + "quick.html\n" + + "\n" + + "\n" + + "The quick brown fox jumps over the lazy dog\n" + + "\n" + + "\n" + + "\n" + + "quick.pdf\n" + + "\n" + + "\n" + + "The quick brown fox jumps over the lazy dog" + + "\n" + + "\n"); } @Test public void zipToTextExcludeArchiveTest() throws Exception { transform(ARCHIVE, ZIP, TXT, MIMETYPE_ZIP, MIMETYPE_TEXT_PLAIN, - false, "\n" + - "folder/subfolder/quick.jpg\n" + - "\n" + - "\n" + - "quick.doc\n" + - "\n" + - "\n" + - "quick.html\n" + - "\n" + - "\n" + - "quick.pdf\n" + - "\n" + - "\n" + - "quick.txt\n" + - "\n" + - "\n" + - "quick.xml\n" + - "\n"); + false, "\n" + + "folder/subfolder/quick.jpg\n" + + "\n" + + "\n" + + "quick.doc\n" + + "\n" + + "\n" + + "quick.html\n" + + "\n" + + "\n" + + "quick.pdf\n" + + "\n" + + "\n" + + "quick.txt\n" + + "\n" + + "\n" + + "quick.xml\n" + + "\n"); } // --- OutlookMsg --- @@ -403,7 +414,8 @@ public class TikaControllerTest extends AbstractTransformerControllerTest @Test public void msgToTxtOutlookMsgTest() throws Exception { - transform(OUTLOOK_MSG, MSG, TXT, MIMETYPE_OUTLOOK_MSG, MIMETYPE_TEXT_PLAIN, null, EXPECTED_MSG_CONTENT_CONTAINS); + transform(OUTLOOK_MSG, MSG, TXT, MIMETYPE_OUTLOOK_MSG, MIMETYPE_TEXT_PLAIN, null, + EXPECTED_MSG_CONTENT_CONTAINS); } // --- PdfBox --- @@ -411,31 +423,36 @@ public class TikaControllerTest extends AbstractTransformerControllerTest @Test public void pdfToTxtPdfBoxTest() throws Exception { - transform(PDF_BOX, PDF, TXT, MIMETYPE_PDF, MIMETYPE_TEXT_PLAIN, null, EXPECTED_TEXT_CONTENT_CONTAINS); + transform(PDF_BOX, PDF, TXT, MIMETYPE_PDF, MIMETYPE_TEXT_PLAIN, null, + EXPECTED_TEXT_CONTENT_CONTAINS); } @Test public void pdfToCsvPdfBoxTest() throws Exception { - transform(PDF_BOX, PDF, CSV, MIMETYPE_PDF, MIMETYPE_TEXT_CSV, null, EXPECTED_TEXT_CONTENT_CONTAINS); // Yes it is just text + transform(PDF_BOX, PDF, CSV, MIMETYPE_PDF, MIMETYPE_TEXT_CSV, null, + EXPECTED_TEXT_CONTENT_CONTAINS); // Yes it is just text } @Test public void pdfToXmlPdfBoxTest() throws Exception { - transform(PDF_BOX, PDF, XML, MIMETYPE_PDF, MIMETYPE_XML, null, EXPECTED_XHTML_CONTENT_CONTAINS); // Yes it is just XHTML + transform(PDF_BOX, PDF, XML, MIMETYPE_PDF, MIMETYPE_XML, null, + EXPECTED_XHTML_CONTENT_CONTAINS); // Yes it is just XHTML } @Test public void pdfToXhtmlPdfBoxTest() throws Exception { - transform(PDF_BOX, PDF, XHTML, MIMETYPE_PDF, MIMETYPE_XHTML, null, EXPECTED_XHTML_CONTENT_CONTAINS); + transform(PDF_BOX, PDF, XHTML, MIMETYPE_PDF, MIMETYPE_XHTML, null, + EXPECTED_XHTML_CONTENT_CONTAINS); } @Test public void pdfToHtmlPdfBoxTest() throws Exception { - transform(PDF_BOX, PDF, HTML, MIMETYPE_PDF, MIMETYPE_HTML, null, EXPECTED_XHTML_CONTENT_CONTAINS); // Yes it is just XHTML + transform(PDF_BOX, PDF, HTML, MIMETYPE_PDF, MIMETYPE_HTML, null, + EXPECTED_XHTML_CONTENT_CONTAINS); // Yes it is just XHTML } // --- Office --- @@ -443,13 +460,15 @@ public class TikaControllerTest extends AbstractTransformerControllerTest @Test public void msgToTxtOfficeTest() throws Exception { - transform(POI_OFFICE, MSG, TXT, MIMETYPE_OUTLOOK_MSG, MIMETYPE_TEXT_PLAIN, null, EXPECTED_MSG_CONTENT_CONTAINS); + transform(POI_OFFICE, MSG, TXT, MIMETYPE_OUTLOOK_MSG, MIMETYPE_TEXT_PLAIN, null, + EXPECTED_MSG_CONTENT_CONTAINS); } @Test public void docToTxtOfficeTest() throws Exception { - transform(POI_OFFICE, DOC, TXT, MIMETYPE_WORD, MIMETYPE_TEXT_PLAIN, null, EXPECTED_TEXT_CONTENT_CONTAINS); + transform(POI_OFFICE, DOC, TXT, MIMETYPE_WORD, MIMETYPE_TEXT_PLAIN, null, + EXPECTED_TEXT_CONTENT_CONTAINS); } // --- Poi --- @@ -457,7 +476,8 @@ public class TikaControllerTest extends AbstractTransformerControllerTest @Test public void xslxToCsvPoiTest() throws Exception { - transform(POI, XSLX, CSV, MIMETYPE_OPENXML_SPREADSHEET, MIMETYPE_TEXT_CSV, null, EXPECTED_CSV_CONTENT_CONTAINS); + transform(POI, XSLX, CSV, MIMETYPE_OPENXML_SPREADSHEET, MIMETYPE_TEXT_CSV, null, + EXPECTED_CSV_CONTENT_CONTAINS); } // --- OOXML --- @@ -465,13 +485,15 @@ public class TikaControllerTest extends AbstractTransformerControllerTest @Test public void docxToTxtOoXmlTest() throws Exception { - transform(POI_OO_XML, DOCX, TXT, MIMETYPE_OPENXML_WORDPROCESSING, MIMETYPE_TEXT_PLAIN, null, EXPECTED_TEXT_CONTENT_CONTAINS); + transform(POI_OO_XML, DOCX, TXT, MIMETYPE_OPENXML_WORDPROCESSING, MIMETYPE_TEXT_PLAIN, null, + EXPECTED_TEXT_CONTENT_CONTAINS); } @Test public void pptxToTxtOoXmlTest() throws Exception { - transform(POI_OO_XML, PPTX, TXT, MIMETYPE_OPENXML_PRESENTATION, MIMETYPE_TEXT_PLAIN, null, EXPECTED_TEXT_CONTENT_CONTAINS); + transform(POI_OO_XML, PPTX, TXT, MIMETYPE_OPENXML_PRESENTATION, MIMETYPE_TEXT_PLAIN, null, + EXPECTED_TEXT_CONTENT_CONTAINS); } // --- TikaAuto --- @@ -479,13 +501,15 @@ public class TikaControllerTest extends AbstractTransformerControllerTest @Test public void ppxtToTxtTikaAutoTest() throws Exception { - transform(TIKA_AUTO, PPTX, TXT, MIMETYPE_OPENXML_PRESENTATION, MIMETYPE_TEXT_PLAIN, null, EXPECTED_TEXT_CONTENT_CONTAINS); + transform(TIKA_AUTO, PPTX, TXT, MIMETYPE_OPENXML_PRESENTATION, MIMETYPE_TEXT_PLAIN, null, + EXPECTED_TEXT_CONTENT_CONTAINS); } @Test public void doctToTxtTikaAutoTest() throws Exception { - transform(TIKA_AUTO, DOCX, TXT, MIMETYPE_OPENXML_WORDPROCESSING, MIMETYPE_TEXT_PLAIN, null, EXPECTED_TEXT_CONTENT_CONTAINS); + transform(TIKA_AUTO, DOCX, TXT, MIMETYPE_OPENXML_WORDPROCESSING, MIMETYPE_TEXT_PLAIN, null, + EXPECTED_TEXT_CONTENT_CONTAINS); } // --- TextMining --- @@ -493,16 +517,20 @@ public class TikaControllerTest extends AbstractTransformerControllerTest @Test public void docToTxtTextMiningTest() throws Exception { - transform(TEXT_MINING, DOC, TXT, MIMETYPE_WORD, MIMETYPE_TEXT_PLAIN, null, EXPECTED_TEXT_CONTENT_CONTAINS); + transform(TEXT_MINING, DOC, TXT, MIMETYPE_WORD, MIMETYPE_TEXT_PLAIN, null, + EXPECTED_TEXT_CONTENT_CONTAINS); } - + @Test public void pdfToTxtExtractBookmarksTest() throws Exception { mockTransformCommand(PDF, TXT, MIMETYPE_PDF, true); - mockMvc.perform(mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension).param("notExtractBookmarksText", "true")) - .andExpect(status().is(OK.value())) - .andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''quick." + targetExtension)); + mockMvc.perform( + mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension).param( + "notExtractBookmarksText", "true")) + .andExpect(status().is(OK.value())) + .andExpect(header().string("Content-Disposition", + "attachment; filename*= UTF-8''quick." + targetExtension)); } @Override @@ -510,13 +538,13 @@ public class TikaControllerTest extends AbstractTransformerControllerTest { transformRequest.setSourceExtension(sourceExtension); transformRequest.setTargetExtension(targetExtension); - transformRequest.setSourceMediaType(MediaType.APPLICATION_PDF_VALUE); - transformRequest.setTargetMediaType(MediaType.TEXT_PLAIN_VALUE); + transformRequest.setSourceMediaType(APPLICATION_PDF_VALUE); + transformRequest.setTargetMediaType(TEXT_PLAIN_VALUE); transformRequest.getTransformRequestOptions().put("transform", "PdfBox"); - transformRequest.getTransformRequestOptions().put("targetMimetype", MediaType.TEXT_PLAIN_VALUE); + transformRequest.getTransformRequestOptions().put("targetMimetype", TEXT_PLAIN_VALUE); transformRequest.getTransformRequestOptions().put("targetEncoding", "UTF-8"); } - + @Test public void testPojoTransform() throws Exception { @@ -525,7 +553,6 @@ public class TikaControllerTest extends AbstractTransformerControllerTest File sourceFile = getTestFile("quick." + sourceExtension, true); String targetFileRef = UUID.randomUUID().toString(); - // Transformation Request POJO TransformRequest transformRequest = new TransformRequest(); transformRequest.setRequestId("1"); @@ -539,12 +566,13 @@ public class TikaControllerTest extends AbstractTransformerControllerTest // HTTP Request HttpHeaders headers = new HttpHeaders(); - headers.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=quick." + sourceExtension); + headers.set(CONTENT_DISPOSITION, "attachment; filename=quick." + sourceExtension); ResponseEntity response = new ResponseEntity<>(new FileSystemResource( sourceFile), headers, OK); when(alfrescoSharedFileStoreClient.retrieveFile(sourceFileRef)).thenReturn(response); - when(alfrescoSharedFileStoreClient.saveFile(any())).thenReturn(new FileRefResponse(new FileRefEntity(targetFileRef))); + when(alfrescoSharedFileStoreClient.saveFile(any())) + .thenReturn(new FileRefResponse(new FileRefEntity(targetFileRef))); when(mockExecutionResult.getExitValue()).thenReturn(0); // Update the Transformation Request with any specific params before sending it @@ -552,18 +580,21 @@ public class TikaControllerTest extends AbstractTransformerControllerTest // Serialize and call the transformer String tr = objectMapper.writeValueAsString(transformRequest); - String transformationReplyAsString = mockMvc.perform(MockMvcRequestBuilders.post("/transform") - .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).content(tr)) - .andExpect(status().is(HttpStatus.CREATED.value())) - .andReturn().getResponse().getContentAsString(); + String transformationReplyAsString = mockMvc + .perform(MockMvcRequestBuilders + .post("/transform") + .header(ACCEPT, APPLICATION_JSON_VALUE) + .header(CONTENT_TYPE, APPLICATION_JSON_VALUE) + .content(tr)) + .andExpect(status().is(CREATED.value())) + .andReturn().getResponse().getContentAsString(); - TransformReply transformReply = objectMapper.readValue(transformationReplyAsString, TransformReply.class); + TransformReply transformReply = objectMapper.readValue(transformationReplyAsString, + TransformReply.class); // Assert the reply assertEquals(transformRequest.getRequestId(), transformReply.getRequestId()); assertEquals(transformRequest.getClientData(), transformReply.getClientData()); assertEquals(transformRequest.getSchema(), transformReply.getSchema()); } - } diff --git a/alfresco-docker-tika/src/test/java/org/alfresco/transformer/TikaQueueTransformServiceIT.java b/alfresco-docker-tika/src/test/java/org/alfresco/transformer/TikaQueueTransformServiceIT.java index 684f901f..cb376fd8 100644 --- a/alfresco-docker-tika/src/test/java/org/alfresco/transformer/TikaQueueTransformServiceIT.java +++ b/alfresco-docker-tika/src/test/java/org/alfresco/transformer/TikaQueueTransformServiceIT.java @@ -48,7 +48,8 @@ public class TikaQueueTransformServiceIT extends AbstractQueueTransformServiceIT @Override protected TransformRequest buildRequest() { - return TransformRequest.builder() + return TransformRequest + .builder() .withRequestId(UUID.randomUUID().toString()) .withSourceMediaType(MIMETYPE_OPENXML_WORDPROCESSING) .withTargetMediaType(MIMETYPE_TEXT_PLAIN) diff --git a/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/Application.java b/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/Application.java index 212b4253..7fb96120 100644 --- a/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/Application.java +++ b/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/Application.java @@ -26,24 +26,32 @@ */ package org.alfresco.transformer; -import io.micrometer.core.instrument.MeterRegistry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.annotation.Bean; +import org.springframework.context.event.EventListener; + +import io.micrometer.core.instrument.MeterRegistry; @SpringBootApplication -@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) +@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class}) public class Application { + private static final Logger logger = LoggerFactory.getLogger(Application.class); + @Value("${container.name}") private String containerName; @Bean - MeterRegistryCustomizer metricsCommonTags() { + MeterRegistryCustomizer metricsCommonTags() + { return registry -> registry.config().commonTags("containerName", containerName); } @@ -51,4 +59,16 @@ public class Application { SpringApplication.run(Application.class, args); } + + @EventListener(ApplicationReadyEvent.class) + public void startup() + { + logger.info("--------------------------------------------------------------------------------------------------------------------------------------------------------------"); + logger.info("The transformers in this project use libraries from Apache. See the license at http://www.apache.org/licenses/LICENSE-2.0. or in /Apache\\\\ 2.0.txt"); + logger.info("Additional libraries used:"); + logger.info("* htmlparser http://htmlparser.sourceforge.net/license.html"); + logger.info("--------------------------------------------------------------------------------------------------------------------------------------------------------------"); + + logger.info("Starting application components... Done"); + } } diff --git a/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/MiscController.java b/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/MiscController.java index 226fb08d..6d7e632f 100644 --- a/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/MiscController.java +++ b/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/MiscController.java @@ -64,15 +64,6 @@ public class MiscController extends AbstractTransformerController @Autowired private SelectingTransformer transformer; - public MiscController() - { - logger.info("--------------------------------------------------------------------------------------------------------------------------------------------------------------"); - logger.info("The transformers in this project use libraries from Apache. See the license at http://www.apache.org/licenses/LICENSE-2.0. or in /Apache\\\\ 2.0.txt"); - logger.info("Additional libraries used:"); - logger.info("* htmlparser http://htmlparser.sourceforge.net/license.html"); - logger.info("--------------------------------------------------------------------------------------------------------------------------------------------------------------"); - } - @Override public String getTransformerName() { @@ -91,8 +82,8 @@ public class MiscController extends AbstractTransformerController // HtmlParserContentTransformer html -> text // See the Javadoc on this method and Probes.md for the choice of these values. return new ProbeTestTransform(this, "quick.html", "quick.txt", - 119, 30, 150, 1024, - 60*2+1,60*2) + 119, 30, 150, 1024, + 60 * 2 + 1, 60 * 2) { @Override protected void executeTransformCommand(File sourceFile, File targetFile) @@ -100,40 +91,47 @@ public class MiscController extends AbstractTransformerController Map parameters = new HashMap<>(); parameters.put(SOURCE_ENCODING, "UTF-8"); parameters.put(TARGET_ENCODING, "UTF-8"); - transformer.transform(sourceFile, targetFile, MIMETYPE_HTML, MIMETYPE_TEXT_PLAIN, parameters); + transformer.transform(sourceFile, targetFile, MIMETYPE_HTML, MIMETYPE_TEXT_PLAIN, + parameters); } }; } + @Override - public void processTransform(File sourceFile, File targetFile, Map transformOptions, Long timeout) + public void processTransform(File sourceFile, File targetFile, + Map transformOptions, Long timeout) { if (logger.isDebugEnabled()) { - logger.debug("Processing request with: sourceFile '{}', targetFile '{}', transformOptions" + - " '{}', timeout {} ms", sourceFile, targetFile, transformOptions, timeout); + logger.debug( + "Processing request with: sourceFile '{}', targetFile '{}', transformOptions" + + " '{}', timeout {} ms", sourceFile, targetFile, transformOptions, timeout); } String sourceMimetype = transformOptions.get("sourceMimetype"); String targetMimetype = transformOptions.get("targetMimetype"); - transformer.transform(sourceFile, targetFile, sourceMimetype, targetMimetype, transformOptions); + transformer.transform(sourceFile, targetFile, sourceMimetype, targetMimetype, + transformOptions); } @PostMapping(value = "/transform", consumes = MULTIPART_FORM_DATA_VALUE) public ResponseEntity transform(HttpServletRequest request, - @RequestParam("file") MultipartFile sourceMultipartFile, - @RequestParam(value = "targetExtension") String targetExtension, - @RequestParam(value = "targetMimetype") String targetMimetype, - @RequestParam(value = "sourceMimetype") String sourceMimetype, - @RequestParam(value = "testDelay", required = false) Long testDelay, - @RequestParam Map parameters) + @RequestParam("file") MultipartFile sourceMultipartFile, + @RequestParam(value = "targetExtension") String targetExtension, + @RequestParam(value = "targetMimetype") String targetMimetype, + @RequestParam(value = "sourceMimetype") String sourceMimetype, + @RequestParam(value = "testDelay", required = false) Long testDelay, + @RequestParam Map parameters) { if (logger.isDebugEnabled()) { - logger.debug("Processing request with: sourceMimetype '{}', targetMimetype '{}' , targetExtension '{}' " + - ", parameters '{}'", sourceMimetype, targetMimetype, targetExtension, parameters); + logger.debug( + "Processing request with: sourceMimetype '{}', targetMimetype '{}' , targetExtension '{}' " + + ", parameters '{}'", sourceMimetype, targetMimetype, targetExtension, parameters); } - String targetFilename = createTargetFileName(sourceMultipartFile.getOriginalFilename(), targetExtension); + String targetFilename = createTargetFileName(sourceMultipartFile.getOriginalFilename(), + targetExtension); getProbeTestTransform().incrementTransformerCount(); File sourceFile = createSourceFile(request, sourceMultipartFile); File targetFile = createTargetFile(request, targetFilename); diff --git a/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/AppleIWorksContentTransformer.java b/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/AppleIWorksContentTransformer.java index 6495ff53..2c4ddadc 100644 --- a/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/AppleIWorksContentTransformer.java +++ b/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/AppleIWorksContentTransformer.java @@ -26,12 +26,10 @@ */ package org.alfresco.transformer.transformers; -import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.transform.client.model.Mimetype; -import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; -import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_IMAGE_JPEG; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_IWORK_KEYNOTE; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_IWORK_NUMBERS; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_IWORK_PAGES; import java.io.BufferedInputStream; import java.io.File; @@ -39,13 +37,16 @@ import java.io.FileInputStream; import java.io.IOException; import java.nio.file.Files; import java.nio.file.StandardCopyOption; -import java.util.Arrays; import java.util.List; import java.util.Map; -import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_IWORK_KEYNOTE; -import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_IWORK_NUMBERS; -import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_IWORK_PAGES; +import org.alfresco.error.AlfrescoRuntimeException; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; +import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.ImmutableList; /** * Converts Apple iWorks files to JPEGs for thumbnailing & previewing. @@ -60,24 +61,25 @@ import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_IWORK_PAGES; */ public class AppleIWorksContentTransformer implements SelectableTransformer { - private static final Logger logger = LoggerFactory.getLogger(AppleIWorksContentTransformer.class); + private static final Logger logger = LoggerFactory.getLogger( + AppleIWorksContentTransformer.class); // Apple's zip entry names for previews in iWorks have changed over time. - private static final List PDF_PATHS = Arrays.asList( - "QuickLook/Preview.pdf"); // iWorks 2008/9 - private static final List JPG_PATHS = Arrays.asList( - "QuickLook/Thumbnail.jpg", // iWorks 2008/9 - "preview.jpg"); // iWorks 2013/14 (720 x 552) We use the best quality image. Others are: - // (225 x 173) preview-web.jpg - // (53 x 41) preview-micro.jpg + private static final List PDF_PATHS = ImmutableList.of( + "QuickLook/Preview.pdf"); // iWorks 2008/9 + private static final List JPG_PATHS = ImmutableList.of( + "QuickLook/Thumbnail.jpg", // iWorks 2008/9 + "preview.jpg"); // iWorks 2013/14 (720 x 552) We use the best quality image. Others are: + // (225 x 173) preview-web.jpg + // (53 x 41) preview-micro.jpg @Override - public boolean isTransformable(String sourceMimetype, String targetMimetype, Map parameters) + public boolean isTransformable(String sourceMimetype, String targetMimetype, + Map parameters) { - boolean transformable = MIMETYPE_IWORK_KEYNOTE.equals(sourceMimetype) - || MIMETYPE_IWORK_NUMBERS.equals(sourceMimetype) - || MIMETYPE_IWORK_PAGES.equals(sourceMimetype); - return transformable; + return MIMETYPE_IWORK_KEYNOTE.equals(sourceMimetype) || + MIMETYPE_IWORK_NUMBERS.equals(sourceMimetype) || + MIMETYPE_IWORK_PAGES.equals(sourceMimetype); } @Override @@ -86,20 +88,19 @@ public class AppleIWorksContentTransformer implements SelectableTransformer final String sourceMimetype = parameters.get(SOURCE_MIMETYPE); final String targetMimetype = parameters.get(TARGET_MIMETYPE); - if(logger.isDebugEnabled()) - { - logger.debug("Performing IWorks to jpeg transform with sourceMimetype=" + sourceMimetype - + " targetMimetype=" + targetMimetype); - } + logger.debug("Performing IWorks to jpeg transform with sourceMimetype={} targetMimetype={}", + sourceMimetype, targetMimetype); + // iWorks files are zip (or package) files. // If it's not a zip file, the resultant ZipException will be caught as an IOException below. - try (ZipArchiveInputStream iWorksZip = new ZipArchiveInputStream( new BufferedInputStream( new FileInputStream(sourceFile)))) + try (ZipArchiveInputStream iWorksZip = new ZipArchiveInputStream( + new BufferedInputStream(new FileInputStream(sourceFile)))) { // Look through the zip file entries for the preview/thumbnail. - List paths = Mimetype.MIMETYPE_IMAGE_JPEG.equals(targetMimetype) ? JPG_PATHS : PDF_PATHS; + List paths = MIMETYPE_IMAGE_JPEG.equals(targetMimetype) ? JPG_PATHS : PDF_PATHS; ZipArchiveEntry entry; boolean found = false; - while ((entry=iWorksZip.getNextZipEntry()) != null) + while ((entry = iWorksZip.getNextZipEntry()) != null) { String name = entry.getName(); if (paths.contains(name)) @@ -110,14 +111,17 @@ public class AppleIWorksContentTransformer implements SelectableTransformer } } - if (! found) + if (!found) { - throw new AlfrescoRuntimeException("The source " + sourceMimetype + " file did not contain a " + targetMimetype + " preview"); + throw new AlfrescoRuntimeException( + "The source " + sourceMimetype + " file did not contain a " + targetMimetype + " preview"); } } catch (IOException e) { - throw new AlfrescoRuntimeException("Unable to transform " + sourceMimetype + " file. It should have been a zip format file.", e); + throw new AlfrescoRuntimeException( + "Unable to transform " + sourceMimetype + " file. It should have been a zip format file.", + e); } } } diff --git a/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/HtmlParserContentTransformer.java b/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/HtmlParserContentTransformer.java index de87ed3a..a0cac4ad 100644 --- a/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/HtmlParserContentTransformer.java +++ b/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/HtmlParserContentTransformer.java @@ -26,16 +26,12 @@ */ package org.alfresco.transformer.transformers; -import org.htmlparser.Parser; -import org.htmlparser.beans.StringBean; -import org.htmlparser.util.ParserException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_HTML; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_TEXT_PLAIN; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; -import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.net.URLConnection; @@ -43,8 +39,11 @@ import java.nio.charset.Charset; import java.nio.charset.IllegalCharsetNameException; import java.util.Map; -import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_HTML; -import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_TEXT_PLAIN; +import org.htmlparser.Parser; +import org.htmlparser.beans.StringBean; +import org.htmlparser.util.ParserException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Content transformer which wraps the HTML Parser library for @@ -63,34 +62,36 @@ import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_TEXT_PLAIN; * *

* Tika Note - could be converted to use the Tika HTML parser, - * but we'd potentially need a custom text handler to replicate - * the current settings around links and non-breaking spaces. + * but we'd potentially need a custom text handler to replicate + * the current settings around links and non-breaking spaces. *

* - * @see http://htmlparser.sourceforge.net - * @see org.htmlparser.beans.StringBean - * @see HTML Parser - * * @author Derek Hulley * @author eknizat + * @see http://htmlparser.sourceforge.net + * @see org.htmlparser.beans.StringBean + * @see HTML Parser */ public class HtmlParserContentTransformer implements SelectableTransformer { - private static final Logger logger = LoggerFactory.getLogger(HtmlParserContentTransformer.class); + private static final Logger logger = LoggerFactory.getLogger( + HtmlParserContentTransformer.class); @Override - public boolean isTransformable(String sourceMimetype, String targetMimetype, Map parameters) + public boolean isTransformable(String sourceMimetype, String targetMimetype, + Map parameters) { return MIMETYPE_HTML.equals(sourceMimetype) && MIMETYPE_TEXT_PLAIN.equals(targetMimetype); } @Override - public void transform(File sourceFile, File targetFile, Map parameters) throws Exception + public void transform(File sourceFile, File targetFile, Map parameters) + throws Exception { String sourceEncoding = parameters.get(SOURCE_ENCODING); checkEncodingParameter(sourceEncoding, SOURCE_ENCODING); - if(logger.isDebugEnabled()) + if (logger.isDebugEnabled()) { logger.debug("Performing HTML to text transform with sourceEncoding=" + sourceEncoding); } @@ -105,42 +106,42 @@ public class HtmlParserContentTransformer implements SelectableTransformer String text = extractor.getStrings(); // write it to the writer - try ( Writer writer = new BufferedWriter( new OutputStreamWriter(new FileOutputStream(targetFile)))) + try (Writer writer = new BufferedWriter( + new OutputStreamWriter(new FileOutputStream(targetFile)))) { writer.write(text); } } - private void checkEncodingParameter(String encoding, String paramterName) + private void checkEncodingParameter(String encoding, String parameterName) { try { if (encoding != null && !Charset.isSupported(encoding)) { - throw new IllegalArgumentException(paramterName + "=" + encoding + " is not supported by the JVM."); + throw new IllegalArgumentException( + parameterName + "=" + encoding + " is not supported by the JVM."); } } catch (IllegalCharsetNameException e) { - throw new IllegalArgumentException(paramterName + "=" + encoding + " is not a valid encoding."); + throw new IllegalArgumentException( + parameterName + "=" + encoding + " is not a valid encoding."); } } /** - * - *

- * This code is based on a class of the same name, originally implemented in alfresco-repository. - *

+ *

+ * This code is based on a class of the same name, originally implemented in alfresco-repository. + *

* * A version of {@link StringBean} which allows control of the - * encoding in the underlying HTML Parser. + * encoding in the underlying HTML Parser. * Unfortunately, StringBean doesn't allow easy over-riding of - * this, so we have to duplicate some code to control this. + * this, so we have to duplicate some code to control this. * This allows us to correctly handle HTML files where the encoding - * is specified against the content property (rather than in the - * HTML Head Meta), see ALF-10466 for details. - * - * + * is specified against the content property (rather than in the + * HTML Head Meta), see ALF-10466 for details. */ private class EncodingAwareStringBean extends StringBean { @@ -148,9 +149,9 @@ public class HtmlParserContentTransformer implements SelectableTransformer /** * Sets the File to extract strings from, and the encoding - * it's in (if known to Alfresco) + * it's in (if known to Alfresco) * - * @param file The File that text should be fetched from. + * @param file The File that text should be fetched from. * @param encoding The encoding of the input */ public void setURL(File file, String encoding) @@ -158,7 +159,7 @@ public class HtmlParserContentTransformer implements SelectableTransformer String previousURL = getURL(); String newURL = file.getAbsolutePath(); - if ( (previousURL == null) || (!newURL.equals(previousURL)) ) + if (previousURL == null || !newURL.equals(previousURL)) { try { @@ -178,8 +179,10 @@ public class HtmlParserContentTransformer implements SelectableTransformer mParser.setEncoding(encoding); } - mPropertySupport.firePropertyChange(StringBean.PROP_URL_PROPERTY, previousURL, getURL()); - mPropertySupport.firePropertyChange(StringBean.PROP_CONNECTION_PROPERTY, conn, mParser.getConnection()); + mPropertySupport.firePropertyChange(StringBean.PROP_URL_PROPERTY, previousURL, + getURL()); + mPropertySupport.firePropertyChange(StringBean.PROP_CONNECTION_PROPERTY, conn, + mParser.getConnection()); setStrings(); } catch (ParserException pe) @@ -189,7 +192,8 @@ public class HtmlParserContentTransformer implements SelectableTransformer } } - public String getEncoding(){ + public String getEncoding() + { return mParser.getEncoding(); } } diff --git a/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/OOXMLThumbnailContentTransformer.java b/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/OOXMLThumbnailContentTransformer.java index a2f81a20..0a39709d 100644 --- a/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/OOXMLThumbnailContentTransformer.java +++ b/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/OOXMLThumbnailContentTransformer.java @@ -26,8 +26,36 @@ */ package org.alfresco.transformer.transformers; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_IMAGE_JPEG; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_OPENXML_PRESENTATION; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_OPENXML_PRESENTATION_ADDIN; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_OPENXML_PRESENTATION_MACRO; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_OPENXML_PRESENTATION_SLIDE; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_OPENXML_PRESENTATION_SLIDESHOW; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_OPENXML_PRESENTATION_SLIDESHOW_MACRO; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_OPENXML_PRESENTATION_SLIDE_MACRO; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_OPENXML_PRESENTATION_TEMPLATE; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_OPENXML_PRESENTATION_TEMPLATE_MACRO; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_OPENXML_SPREADSHEET; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_OPENXML_SPREADSHEET_ADDIN_MACRO; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_OPENXML_SPREADSHEET_BINARY_MACRO; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_OPENXML_SPREADSHEET_MACRO; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_OPENXML_SPREADSHEET_TEMPLATE; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_OPENXML_SPREADSHEET_TEMPLATE_MACRO; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_OPENXML_WORDPROCESSING; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_OPENXML_WORDPROCESSING_MACRO; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_OPENXML_WORD_TEMPLATE; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_OPENXML_WORD_TEMPLATE_MACRO; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.util.List; +import java.util.Map; + import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.transform.client.model.Mimetype; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackageRelationship; @@ -36,74 +64,70 @@ import org.apache.poi.openxml4j.opc.PackageRelationshipTypes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.StandardCopyOption; -import java.util.Arrays; -import java.util.List; -import java.util.Map; +import com.google.common.collect.ImmutableList; /** * Extracts out Thumbnail JPEGs from OOXML files for thumbnailing & previewing. * This transformer will only work for OOXML files where thumbnailing was enabled, - * which isn't on by default on Windows, but is more common on Mac. + * which isn't on by default on Windows, but is more common on Mac. * * @author Nick Burch * @author eknizat - * */ public class OOXMLThumbnailContentTransformer implements SelectableTransformer { - private static final Logger logger = LoggerFactory.getLogger(OOXMLThumbnailContentTransformer.class); + private static final Logger logger = LoggerFactory.getLogger( + OOXMLThumbnailContentTransformer.class); - private static final List OOXML_MIMETYPES = Arrays.asList(new String[]{ - Mimetype.MIMETYPE_OPENXML_WORDPROCESSING, - Mimetype.MIMETYPE_OPENXML_WORDPROCESSING_MACRO, - Mimetype.MIMETYPE_OPENXML_WORD_TEMPLATE, - Mimetype.MIMETYPE_OPENXML_WORD_TEMPLATE_MACRO, - Mimetype.MIMETYPE_OPENXML_PRESENTATION, - Mimetype.MIMETYPE_OPENXML_PRESENTATION_MACRO, - Mimetype.MIMETYPE_OPENXML_PRESENTATION_SLIDESHOW, - Mimetype.MIMETYPE_OPENXML_PRESENTATION_SLIDESHOW_MACRO, - Mimetype.MIMETYPE_OPENXML_PRESENTATION_TEMPLATE, - Mimetype.MIMETYPE_OPENXML_PRESENTATION_TEMPLATE_MACRO, - Mimetype.MIMETYPE_OPENXML_PRESENTATION_ADDIN, - Mimetype.MIMETYPE_OPENXML_PRESENTATION_SLIDE, - Mimetype.MIMETYPE_OPENXML_PRESENTATION_SLIDE_MACRO, - Mimetype.MIMETYPE_OPENXML_SPREADSHEET, - Mimetype.MIMETYPE_OPENXML_SPREADSHEET_TEMPLATE, - Mimetype.MIMETYPE_OPENXML_SPREADSHEET_MACRO, - Mimetype.MIMETYPE_OPENXML_SPREADSHEET_TEMPLATE_MACRO, - Mimetype.MIMETYPE_OPENXML_SPREADSHEET_ADDIN_MACRO, - Mimetype.MIMETYPE_OPENXML_SPREADSHEET_BINARY_MACRO}); + private static final List OOXML_MIMETYPES = ImmutableList.of( + MIMETYPE_OPENXML_WORDPROCESSING, + MIMETYPE_OPENXML_WORDPROCESSING_MACRO, + MIMETYPE_OPENXML_WORD_TEMPLATE, + MIMETYPE_OPENXML_WORD_TEMPLATE_MACRO, + MIMETYPE_OPENXML_PRESENTATION, + MIMETYPE_OPENXML_PRESENTATION_MACRO, + MIMETYPE_OPENXML_PRESENTATION_SLIDESHOW, + MIMETYPE_OPENXML_PRESENTATION_SLIDESHOW_MACRO, + MIMETYPE_OPENXML_PRESENTATION_TEMPLATE, + MIMETYPE_OPENXML_PRESENTATION_TEMPLATE_MACRO, + MIMETYPE_OPENXML_PRESENTATION_ADDIN, + MIMETYPE_OPENXML_PRESENTATION_SLIDE, + MIMETYPE_OPENXML_PRESENTATION_SLIDE_MACRO, + MIMETYPE_OPENXML_SPREADSHEET, + MIMETYPE_OPENXML_SPREADSHEET_TEMPLATE, + MIMETYPE_OPENXML_SPREADSHEET_MACRO, + MIMETYPE_OPENXML_SPREADSHEET_TEMPLATE_MACRO, + MIMETYPE_OPENXML_SPREADSHEET_ADDIN_MACRO, + MIMETYPE_OPENXML_SPREADSHEET_BINARY_MACRO); @Override - public boolean isTransformable(String sourceMimetype, String targetMimetype, Map parameters) + public boolean isTransformable(String sourceMimetype, String targetMimetype, + Map parameters) { // only support [OOXML] -> JPEG - return Mimetype.MIMETYPE_IMAGE_JPEG.equals(targetMimetype) && OOXML_MIMETYPES.contains(sourceMimetype); + return MIMETYPE_IMAGE_JPEG.equals(targetMimetype) && + OOXML_MIMETYPES.contains(sourceMimetype); } @Override - public void transform(File sourceFile, File targetFile, Map parameters) throws Exception + public void transform(File sourceFile, File targetFile, Map parameters) + throws Exception { final String sourceMimetype = parameters.get(SOURCE_MIMETYPE); final String targetMimetype = parameters.get(TARGET_MIMETYPE); - if(logger.isDebugEnabled()) + if (logger.isDebugEnabled()) { logger.debug("Performing OOXML to jpeg transform with sourceMimetype=" + sourceMimetype - + " targetMimetype=" + targetMimetype); + + " targetMimetype=" + targetMimetype); } try (OPCPackage pkg = OPCPackage.open(sourceFile.getPath())) { // Does it have a thumbnail? - PackageRelationshipCollection rels = pkg.getRelationshipsByType(PackageRelationshipTypes.THUMBNAIL); + PackageRelationshipCollection rels = pkg.getRelationshipsByType( + PackageRelationshipTypes.THUMBNAIL); if (rels.size() > 0) { // Get the thumbnail part @@ -118,7 +142,8 @@ public class OOXMLThumbnailContentTransformer implements SelectableTransformer else { logger.debug("No thumbnail present in file."); - throw new Exception("No thumbnail present in file, unable to generate " + targetMimetype); + throw new Exception( + "No thumbnail present in file, unable to generate " + targetMimetype); } } catch (IOException e) diff --git a/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/SelectableTransformer.java b/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/SelectableTransformer.java index 523c7f83..53103768 100644 --- a/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/SelectableTransformer.java +++ b/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/SelectableTransformer.java @@ -26,15 +26,10 @@ */ package org.alfresco.transformer.transformers; -import org.alfresco.transformer.logging.LogEntry; - import java.io.File; import java.util.Map; -import java.util.Set; -import java.util.StringJoiner; /** - * * Implemented by transformers used by {@link SelectingTransformer}. * * @author eknizat @@ -48,21 +43,23 @@ public interface SelectableTransformer /** * Implementation of the actual transformation. + * * @param sourceFile * @param targetFile * @param parameters * @throws Exception */ - public void transform(File sourceFile, File targetFile, Map parameters) throws Exception; - + void transform(File sourceFile, File targetFile, Map parameters) + throws Exception; /** * Determine whether this transformer is applicable for the given MIME types. + * * @param sourceMimetype * @param targetMimetype * @param parameters * @return */ - public boolean isTransformable(String sourceMimetype, String targetMimetype, Map parameters); - + boolean isTransformable(String sourceMimetype, String targetMimetype, + Map parameters); } diff --git a/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/SelectingTransformer.java b/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/SelectingTransformer.java index 077c2117..ffd1760a 100644 --- a/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/SelectingTransformer.java +++ b/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/SelectingTransformer.java @@ -26,6 +26,14 @@ */ package org.alfresco.transformer.transformers; +import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; + +import java.io.File; +import java.util.List; +import java.util.Map; +import java.util.StringJoiner; + import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.transform.exceptions.TransformException; import org.alfresco.transformer.logging.LogEntry; @@ -33,52 +41,47 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import java.io.File; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.StringJoiner; - -import static org.springframework.http.HttpStatus.BAD_REQUEST; -import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; +import com.google.common.collect.ImmutableList; /** - * * The SelectingTransformer selects a registered {@link SelectableTransformer} * and delegates the transformation to its implementation. * * @author eknizat - * */ @Component public class SelectingTransformer { private static final Logger logger = LoggerFactory.getLogger(SelectingTransformer.class); - private List transformers = new LinkedList<>(); + private final List transformers; public SelectingTransformer() { - transformers.add(new AppleIWorksContentTransformer()); - transformers.add(new HtmlParserContentTransformer()); - transformers.add(new StringExtractingContentTransformer()); - transformers.add(new TextToPdfContentTransformer()); -// transformers.add(new OOXMLThumbnailContentTransformer()); // Doesn't work with java 11, transformer and test disabled + transformers = ImmutableList.of( + new AppleIWorksContentTransformer(), + new HtmlParserContentTransformer(), + new StringExtractingContentTransformer(), + new TextToPdfContentTransformer() + // new OOXMLThumbnailContentTransformer()); // Doesn't work with java 11, transformer and test disabled + ); } /** * Performs a transform using a transformer selected based on the provided sourceMimetype and targetMimetype - * @param sourceFile File to transform from - * @param targetFile File to transform to + * + * @param sourceFile File to transform from + * @param targetFile File to transform to * @param sourceMimetype Mimetype of the source file * @throws TransformException */ - public void transform(File sourceFile, File targetFile, String sourceMimetype, String targetMimetype, - Map parameters) throws TransformException + public void transform(File sourceFile, File targetFile, String sourceMimetype, + String targetMimetype, Map parameters) throws TransformException { try { - SelectableTransformer transformer = selectTransformer(sourceMimetype, targetMimetype, parameters); + final SelectableTransformer transformer = selectTransformer(sourceMimetype, + targetMimetype, parameters); logOptions(sourceFile, targetFile, parameters); transformer.transform(sourceFile, targetFile, parameters); } @@ -93,32 +96,30 @@ public class SelectingTransformer if (!targetFile.exists()) { throw new TransformException(INTERNAL_SERVER_ERROR.value(), - "Transformer failed to create an output file. Target file does not exist."); + "Transformer failed to create an output file. Target file does not exist."); } if (sourceFile.length() > 0 && targetFile.length() == 0) { throw new TransformException(INTERNAL_SERVER_ERROR.value(), - "Transformer failed to create an output file. Target file is empty but source file was not empty."); + "Transformer failed to create an output file. Target file is empty but source file was not empty."); } } private SelectableTransformer selectTransformer(String sourceMimetype, String targetMimetype, - Map parameters) + Map parameters) { for (SelectableTransformer transformer : transformers) { if (transformer.isTransformable(sourceMimetype, targetMimetype, parameters)) { - if (logger.isDebugEnabled()) - { - logger.debug("Using " + transformer.getClass().getName() - + " to transform from " + sourceMimetype + " to " + targetMimetype ); - } + logger.debug("Using {} to transform from {} to {}", + transformer.getClass().getName(), sourceMimetype, targetMimetype); return transformer; } } - throw new AlfrescoRuntimeException( "Could not select a transformer for sourceMimetype=" + sourceMimetype - + " targetMimetype=" + targetMimetype); + throw new AlfrescoRuntimeException( + "Could not select a transformer for sourceMimetype=" + sourceMimetype + + " targetMimetype=" + targetMimetype); } private static String getMessage(Exception e) @@ -129,7 +130,8 @@ public class SelectingTransformer private void logOptions(File sourceFile, File targetFile, Map parameters) { StringJoiner sj = new StringJoiner(" "); - parameters.forEach( (k, v) -> sj.add("--" + k + "=" + v)); // keeping the existing style used in other T-Engines + parameters.forEach((k, v) -> sj.add( + "--" + k + "=" + v)); // keeping the existing style used in other T-Engines sj.add(getExtension(sourceFile)); sj.add(getExtension(targetFile)); LogEntry.setOptions(sj.toString()); @@ -137,9 +139,8 @@ public class SelectingTransformer private String getExtension(File file) { - String name = file.getName(); + final String name = file.getName(); int i = name.lastIndexOf('.'); - String ext = i == -1 ? "???" : name.substring(i + 1); - return ext; + return i == -1 ? "???" : name.substring(i + 1); } } diff --git a/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/StringExtractingContentTransformer.java b/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/StringExtractingContentTransformer.java index 7a06137a..c9be21e5 100644 --- a/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/StringExtractingContentTransformer.java +++ b/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/StringExtractingContentTransformer.java @@ -26,29 +26,25 @@ */ package org.alfresco.transformer.transformers; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_DITA; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_JAVASCRIPT; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_TEXT_PLAIN; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.FileOutputStream; -import java.io.IOException; import java.io.InputStreamReader; -import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; -import java.io.UnsupportedEncodingException; import java.io.Writer; import java.nio.charset.Charset; import java.nio.charset.IllegalCharsetNameException; import java.util.Map; -import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_DITA; -import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_JAVASCRIPT; -import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_TEXT_PLAIN; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; /** * Converts any textual format to plain text. @@ -60,7 +56,6 @@ import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_TEXT_PLAIN; * This code is based on a class of the same name originally implemented in alfresco-repository. *

* - * * @author Derek Hulley * @author eknizat */ @@ -70,13 +65,13 @@ public class StringExtractingContentTransformer implements SelectableTransformer private static final Log logger = LogFactory.getLog(StringExtractingContentTransformer.class); @Override - public boolean isTransformable(String sourceMimetype, String targetMimetype, Map parameters) + public boolean isTransformable(String sourceMimetype, String targetMimetype, + Map parameters) { - boolean transformable = (sourceMimetype.startsWith("text/") + return (sourceMimetype.startsWith("text/") || MIMETYPE_JAVASCRIPT.equals(sourceMimetype) || MIMETYPE_DITA.equals(sourceMimetype)) - && MIMETYPE_TEXT_PLAIN.equals(targetMimetype); - return transformable; + && MIMETYPE_TEXT_PLAIN.equals(targetMimetype); } /** @@ -88,16 +83,17 @@ public class StringExtractingContentTransformer implements SelectableTransformer * be unformatted but valid. */ @Override - public void transform(File sourceFile, File targetFile, Map parameters) throws Exception + public void transform(File sourceFile, File targetFile, Map parameters) + throws Exception { String sourceEncoding = parameters.get(SOURCE_ENCODING); String targetEncoding = parameters.get(TARGET_ENCODING); - if(logger.isDebugEnabled()) + if (logger.isDebugEnabled()) { logger.debug("Performing text to text transform with sourceEncoding=" + sourceEncoding - + " targetEncoding=" + targetEncoding); + + " targetEncoding=" + targetEncoding); } Reader charReader = null; @@ -107,23 +103,27 @@ public class StringExtractingContentTransformer implements SelectableTransformer // Build reader if (sourceEncoding == null) { - charReader = new BufferedReader(new InputStreamReader(new FileInputStream(sourceFile))); + charReader = new BufferedReader( + new InputStreamReader(new FileInputStream(sourceFile))); } else { checkEncodingParameter(sourceEncoding, SOURCE_ENCODING); - charReader = new BufferedReader(new InputStreamReader(new FileInputStream(sourceFile), sourceEncoding)); + charReader = new BufferedReader( + new InputStreamReader(new FileInputStream(sourceFile), sourceEncoding)); } // Build writer if (targetEncoding == null) { - charWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(targetFile))); + charWriter = new BufferedWriter( + new OutputStreamWriter(new FileOutputStream(targetFile))); } else { - checkEncodingParameter( targetEncoding, TARGET_ENCODING); - charWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(targetFile), targetEncoding)); + checkEncodingParameter(targetEncoding, TARGET_ENCODING); + charWriter = new BufferedWriter( + new OutputStreamWriter(new FileOutputStream(targetFile), targetEncoding)); } // copy from the one to the other @@ -157,12 +157,14 @@ public class StringExtractingContentTransformer implements SelectableTransformer { if (!Charset.isSupported(encoding)) { - throw new IllegalArgumentException(paramterName + "=" + encoding + " is not supported by the JVM."); + throw new IllegalArgumentException( + paramterName + "=" + encoding + " is not supported by the JVM."); } } catch (IllegalCharsetNameException e) { - throw new IllegalArgumentException(paramterName + "=" + encoding + " is not a valid encoding."); + throw new IllegalArgumentException( + paramterName + "=" + encoding + " is not a valid encoding."); } } } diff --git a/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/TextToPdfContentTransformer.java b/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/TextToPdfContentTransformer.java index 530f61e1..dd05b91b 100644 --- a/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/TextToPdfContentTransformer.java +++ b/alfresco-docker-transform-misc/src/main/java/org/alfresco/transformer/transformers/TextToPdfContentTransformer.java @@ -26,14 +26,11 @@ */ package org.alfresco.transformer.transformers; -import org.alfresco.error.AlfrescoRuntimeException; -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.pdmodel.PDPage; -import org.apache.pdfbox.pdmodel.PDPageContentStream; -import org.apache.pdfbox.pdmodel.font.PDType1Font; -import org.apache.pdfbox.tools.TextToPDF; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_DITA; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_PDF; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_TEXT_CSV; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_TEXT_PLAIN; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_XML; import java.io.BufferedOutputStream; import java.io.BufferedReader; @@ -49,14 +46,16 @@ import java.nio.charset.Charset; import java.util.HashMap; import java.util.Map; -import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_DITA; -import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_PDF; -import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_TEXT_CSV; -import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_TEXT_PLAIN; -import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_XML; +import org.alfresco.error.AlfrescoRuntimeException; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDPageContentStream; +import org.apache.pdfbox.pdmodel.font.PDType1Font; +import org.apache.pdfbox.tools.TextToPDF; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * *

* This code is based on a class of the same name originally implemented in alfresco-repository. *

@@ -65,14 +64,14 @@ import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_XML; * * @author Derek Hulley * @author eknizat -*/ + */ public class TextToPdfContentTransformer implements SelectableTransformer { private static final Logger logger = LoggerFactory.getLogger(TextToPdfContentTransformer.class); public static final String PAGE_LIMIT = "pageLimit"; - private PagedTextToPDF transformer; + private final PagedTextToPDF transformer; public TextToPdfContentTransformer() { @@ -83,11 +82,12 @@ public class TextToPdfContentTransformer implements SelectableTransformer { try { - transformer.setFont(transformer.getStandardFont(fontName)); + transformer.setFont(PagedTextToPDF.getStandardFont(fontName)); } catch (Throwable e) { - throw new AlfrescoRuntimeException("Unable to set Standard Font for PDF generation: " + fontName, e); + throw new AlfrescoRuntimeException( + "Unable to set Standard Font for PDF generation: " + fontName, e); } } @@ -99,29 +99,30 @@ public class TextToPdfContentTransformer implements SelectableTransformer } catch (Throwable e) { - throw new AlfrescoRuntimeException("Unable to set Font Size for PDF generation: " + fontSize); + throw new AlfrescoRuntimeException( + "Unable to set Font Size for PDF generation: " + fontSize); } } @Override - public boolean isTransformable(String sourceMimetype, String targetMimetype, Map parameters) + public boolean isTransformable(String sourceMimetype, String targetMimetype, + Map parameters) { - boolean transformable = ( (MIMETYPE_TEXT_PLAIN.equals(sourceMimetype) - || MIMETYPE_TEXT_CSV.equals(sourceMimetype) - || MIMETYPE_DITA.equals(sourceMimetype) - || MIMETYPE_XML.equals(sourceMimetype) ) - && MIMETYPE_PDF.equals(targetMimetype)); - - return transformable; + return (MIMETYPE_TEXT_PLAIN.equals(sourceMimetype) || + MIMETYPE_TEXT_CSV.equals(sourceMimetype) || + MIMETYPE_DITA.equals(sourceMimetype) || + MIMETYPE_XML.equals(sourceMimetype)) && + MIMETYPE_PDF.equals(targetMimetype); } @Override - public void transform(File sourceFile, File targetFile, Map parameters) throws Exception + public void transform(File sourceFile, File targetFile, Map parameters) + throws Exception { String sourceEncoding = parameters.get(SOURCE_ENCODING); String stringPageLimit = parameters.get(PAGE_LIMIT); int pageLimit = -1; - if ( stringPageLimit != null) + if (stringPageLimit != null) { pageLimit = parseInt(stringPageLimit, PAGE_LIMIT); } @@ -148,18 +149,19 @@ public class TextToPdfContentTransformer implements SelectableTransformer protected InputStreamReader buildReader(InputStream is, String encoding) { // If they gave an encoding, try to use it - if(encoding != null) + if (encoding != null) { Charset charset = null; try { charset = Charset.forName(encoding); - } catch(Exception e) + } + catch (Exception e) { logger.warn("JVM doesn't understand encoding '" + encoding + - "' when transforming text to pdf"); + "' when transforming text to pdf"); } - if(charset != null) + if (charset != null) { logger.debug("Processing plain text in encoding " + charset.displayName()); return new InputStreamReader(is, charset); @@ -175,24 +177,31 @@ public class TextToPdfContentTransformer implements SelectableTransformer { // REPO-1066: duplicating the following lines from org.apache.pdfbox.tools.TextToPDF because they made them private // before the upgrade to pdfbox 2.0.8, in pdfbox 1.8, this piece of code was public in org.apache.pdfbox.pdmodel.font.PDType1Font - static PDType1Font getStandardFont(String name) { - return (PDType1Font)STANDARD_14.get(name); + static PDType1Font getStandardFont(String name) + { + return STANDARD_14.get(name); } - private static final Map STANDARD_14 = new HashMap(); + + private static final Map STANDARD_14 = new HashMap<>(); + static { STANDARD_14.put(PDType1Font.TIMES_ROMAN.getBaseFont(), PDType1Font.TIMES_ROMAN); STANDARD_14.put(PDType1Font.TIMES_BOLD.getBaseFont(), PDType1Font.TIMES_BOLD); STANDARD_14.put(PDType1Font.TIMES_ITALIC.getBaseFont(), PDType1Font.TIMES_ITALIC); - STANDARD_14.put(PDType1Font.TIMES_BOLD_ITALIC.getBaseFont(), PDType1Font.TIMES_BOLD_ITALIC); + STANDARD_14.put(PDType1Font.TIMES_BOLD_ITALIC.getBaseFont(), + PDType1Font.TIMES_BOLD_ITALIC); STANDARD_14.put(PDType1Font.HELVETICA.getBaseFont(), PDType1Font.HELVETICA); STANDARD_14.put(PDType1Font.HELVETICA_BOLD.getBaseFont(), PDType1Font.HELVETICA_BOLD); - STANDARD_14.put(PDType1Font.HELVETICA_OBLIQUE.getBaseFont(), PDType1Font.HELVETICA_OBLIQUE); - STANDARD_14.put(PDType1Font.HELVETICA_BOLD_OBLIQUE.getBaseFont(), PDType1Font.HELVETICA_BOLD_OBLIQUE); + STANDARD_14.put(PDType1Font.HELVETICA_OBLIQUE.getBaseFont(), + PDType1Font.HELVETICA_OBLIQUE); + STANDARD_14.put(PDType1Font.HELVETICA_BOLD_OBLIQUE.getBaseFont(), + PDType1Font.HELVETICA_BOLD_OBLIQUE); STANDARD_14.put(PDType1Font.COURIER.getBaseFont(), PDType1Font.COURIER); STANDARD_14.put(PDType1Font.COURIER_BOLD.getBaseFont(), PDType1Font.COURIER_BOLD); STANDARD_14.put(PDType1Font.COURIER_OBLIQUE.getBaseFont(), PDType1Font.COURIER_OBLIQUE); - STANDARD_14.put(PDType1Font.COURIER_BOLD_OBLIQUE.getBaseFont(), PDType1Font.COURIER_BOLD_OBLIQUE); + STANDARD_14.put(PDType1Font.COURIER_BOLD_OBLIQUE.getBaseFont(), + PDType1Font.COURIER_BOLD_OBLIQUE); STANDARD_14.put(PDType1Font.SYMBOL.getBaseFont(), PDType1Font.SYMBOL); STANDARD_14.put(PDType1Font.ZAPF_DINGBATS.getBaseFont(), PDType1Font.ZAPF_DINGBATS); } @@ -202,7 +211,7 @@ public class TextToPdfContentTransformer implements SelectableTransformer // checks for page limits. // The calling code must close the PDDocument once finished with it. public PDDocument createPDFFromText(Reader text, int pageLimit) - throws IOException + throws IOException { //int pageLimit = (int)pageLimits.getValue(); PDDocument doc = null; @@ -210,23 +219,23 @@ public class TextToPdfContentTransformer implements SelectableTransformer try { final int margin = 40; - float height = getFont().getFontDescriptor().getFontBoundingBox().getHeight()/1000; + float height = getFont().getFontDescriptor().getFontBoundingBox().getHeight() / 1000; //calculate font height and increase by 5 percent. - height = height*getFontSize()*1.05f; + height = height * getFontSize() * 1.05f; doc = new PDDocument(); - BufferedReader data = new BufferedReader( text ); - String nextLine = null; + BufferedReader data = new BufferedReader(text); + String nextLine; PDPage page = new PDPage(); PDPageContentStream contentStream = null; float y = -1; - float maxStringLength = page.getMediaBox().getWidth() - 2*margin; + float maxStringLength = page.getMediaBox().getWidth() - 2 * margin; // There is a special case of creating a PDF document from an empty string. boolean textIsEmpty = true; outer: - while( (nextLine = data.readLine()) != null ) + while ((nextLine = data.readLine()) != null) { // The input text is nonEmpty. New pages will be created and added @@ -234,29 +243,30 @@ public class TextToPdfContentTransformer implements SelectableTransformer // the text. textIsEmpty = false; - String[] lineWords = nextLine.trim().split( " " ); + String[] lineWords = nextLine.trim().split(" "); int lineIndex = 0; - while( lineIndex < lineWords.length ) + while (lineIndex < lineWords.length) { - StringBuffer nextLineToDraw = new StringBuffer(); + final StringBuilder nextLineToDraw = new StringBuilder(); float lengthIfUsingNextWord = 0; do { - nextLineToDraw.append( lineWords[lineIndex] ); - nextLineToDraw.append( " " ); + nextLineToDraw.append(lineWords[lineIndex]); + nextLineToDraw.append(" "); lineIndex++; - if( lineIndex < lineWords.length ) + if (lineIndex < lineWords.length) { String lineWithNextWord = nextLineToDraw.toString() + lineWords[lineIndex]; lengthIfUsingNextWord = - (getFont().getStringWidth( lineWithNextWord )/1000) * getFontSize(); + (getFont().getStringWidth( + lineWithNextWord) / 1000) * getFontSize(); } } - while( lineIndex < lineWords.length && - lengthIfUsingNextWord < maxStringLength ); - if( y < margin ) + while (lineIndex < lineWords.length && + lengthIfUsingNextWord < maxStringLength); + if (y < margin) { - int test = pageCount +1; + int test = pageCount + 1; if (pageLimit > 0 && (pageCount++ >= pageLimit)) { // pageLimits.getAction().throwIOExceptionIfRequired("Page limit ("+pageLimit+ @@ -267,8 +277,8 @@ public class TextToPdfContentTransformer implements SelectableTransformer // We have crossed the end-of-page boundary and need to extend the // document by another page. page = new PDPage(); - doc.addPage( page ); - if( contentStream != null ) + doc.addPage(page); + if (contentStream != null) { contentStream.endText(); contentStream.close(); @@ -277,18 +287,17 @@ public class TextToPdfContentTransformer implements SelectableTransformer contentStream.setFont(getFont(), getFontSize()); contentStream.beginText(); y = page.getMediaBox().getHeight() - margin + height; - contentStream.moveTextPositionByAmount( - margin, y ); + contentStream.moveTextPositionByAmount(margin, y); } //System.out.println( "Drawing string at " + x + "," + y ); - if( contentStream == null ) + if (contentStream == null) { - throw new IOException( "Error:Expected non-null content stream." ); + throw new IOException("Error:Expected non-null content stream."); } - contentStream.moveTextPositionByAmount( 0, -height); + contentStream.moveTextPositionByAmount(0, -height); y -= height; - contentStream.drawString( nextLineToDraw.toString() ); + contentStream.drawString(nextLineToDraw.toString()); } } @@ -300,15 +309,15 @@ public class TextToPdfContentTransformer implements SelectableTransformer doc.addPage(page); } - if( contentStream != null ) + if (contentStream != null) { contentStream.endText(); contentStream.close(); } } - catch( IOException io ) + catch (IOException io) { - if( doc != null ) + if (doc != null) { doc.close(); } diff --git a/alfresco-docker-transform-misc/src/test/java/org/alfresco/transformer/MiscControllerTest.java b/alfresco-docker-transform-misc/src/test/java/org/alfresco/transformer/MiscControllerTest.java index bdf505b1..1babb128 100644 --- a/alfresco-docker-transform-misc/src/test/java/org/alfresco/transformer/MiscControllerTest.java +++ b/alfresco-docker-transform-misc/src/test/java/org/alfresco/transformer/MiscControllerTest.java @@ -26,30 +26,7 @@ */ package org.alfresco.transformer; -import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.transform.client.model.TransformRequest; -import org.alfresco.transformer.transformers.AppleIWorksContentTransformer; -import org.alfresco.transformer.transformers.HtmlParserContentTransformer; -import org.alfresco.transformer.transformers.SelectingTransformer; -import org.alfresco.transformer.transformers.StringExtractingContentTransformer; -import org.alfresco.transformer.transformers.TextToPdfContentTransformer; -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.text.PDFTextStripper; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.context.annotation.Import; -import org.springframework.mock.web.MockMultipartFile; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.servlet.MvcResult; -import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; - -import java.io.IOException; -import java.io.StringWriter; -import java.io.UnsupportedEncodingException; - +import static java.nio.charset.StandardCharsets.UTF_8; import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_HTML; import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_IMAGE_JPEG; import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_IWORK_KEYNOTE; @@ -64,18 +41,37 @@ import static org.springframework.http.HttpStatus.OK; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import java.io.IOException; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.transform.client.model.TransformRequest; +import org.alfresco.transformer.transformers.SelectingTransformer; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.text.PDFTextStripper; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.context.annotation.Import; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; + @RunWith(SpringRunner.class) @WebMvcTest(MiscController.class) @Import({SelectingTransformer.class}) public class MiscControllerTest extends AbstractTransformerControllerTest { - @Autowired private MiscController controller; - private String sourceEncoding = "UTF-8"; - private String targetEncoding = "UTF-8"; - private String targetMimetype = MIMETYPE_TEXT_PLAIN; + private final String sourceEncoding = "UTF-8"; + private final String targetEncoding = "UTF-8"; + private final String targetMimetype = MIMETYPE_TEXT_PLAIN; @Before public void before() throws Exception @@ -88,12 +84,13 @@ public class MiscControllerTest extends AbstractTransformerControllerTest expectedSourceFileBytes = readTestFile(sourceExtension); expectedTargetFileBytes = readTestFile(targetExtension); //expectedTargetFileBytes = null; - sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype, expectedSourceFileBytes); - + sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype, + expectedSourceFileBytes); } @Override - protected void mockTransformCommand(String sourceExtension, String targetExtension, String sourceMimetype, boolean readTargetFileBytes) throws IOException + protected void mockTransformCommand(String sourceExtension, String targetExtension, + String sourceMimetype, boolean readTargetFileBytes) throws IOException { } @@ -110,13 +107,14 @@ public class MiscControllerTest extends AbstractTransformerControllerTest @Override // Add extra required parameters to the request. - protected MockHttpServletRequestBuilder mockMvcRequest(String url, MockMultipartFile sourceFile, String... params) + protected MockHttpServletRequestBuilder mockMvcRequest(String url, MockMultipartFile sourceFile, + String... params) { return super.mockMvcRequest(url, sourceFile, params) - .param("targetEncoding", targetEncoding) - .param("sourceEncoding", sourceEncoding) - .param("targetMimetype", targetMimetype) - .param("sourceMimetype", sourceMimetype); + .param("targetEncoding", targetEncoding) + .param("sourceEncoding", sourceEncoding) + .param("targetMimetype", targetMimetype) + .param("sourceMimetype", sourceMimetype); } @Test @@ -130,38 +128,39 @@ public class MiscControllerTest extends AbstractTransformerControllerTest @Test public void testHTMLtoString() throws Exception { - final String NEWLINE = System.getProperty ("line.separator"); + final String NEWLINE = System.getProperty("line.separator"); final String TITLE = "Testing!"; final String TEXT_P1 = "This is some text in English"; final String TEXT_P2 = "This is more text in English"; final String TEXT_P3 = "C'est en Fran\u00e7ais et Espa\u00f1ol"; String partA = "" + TITLE + "" + NEWLINE; String partB = "

" + TEXT_P1 + "

" + NEWLINE + - "

" + TEXT_P2 + "

" + NEWLINE + - "

" + TEXT_P3 + "

" + NEWLINE; + "

" + TEXT_P2 + "

" + NEWLINE + + "

" + TEXT_P3 + "

" + NEWLINE; String partC = ""; final String expected = TITLE + NEWLINE + TEXT_P1 + NEWLINE + TEXT_P2 + NEWLINE + TEXT_P3 + NEWLINE; MvcResult result = sendText("html", - "UTF-8", - MIMETYPE_HTML, - "txt", - MIMETYPE_TEXT_PLAIN, - "UTF-8", - expected.getBytes()); + "UTF-8", + MIMETYPE_HTML, + "txt", + MIMETYPE_TEXT_PLAIN, + "UTF-8", + expected.getBytes()); - String contentResult = new String(result.getResponse().getContentAsByteArray(), targetEncoding); - assertTrue("The content did not include \""+expected, contentResult.contains(expected)); + String contentResult = new String(result.getResponse().getContentAsByteArray(), + targetEncoding); + assertTrue("The content did not include \"" + expected, contentResult.contains(expected)); } @Test public void testStringToString() throws Exception { - String expected = null; - byte[] content = null; + String expected; + byte[] content; try { - content = "azAz10!�$%^&*()\t\r\n".getBytes("UTF-8"); + content = "azAz10!�$%^&*()\t\r\n".getBytes(UTF_8); expected = new String(content, "MacDingbat"); } catch (UnsupportedEncodingException e) @@ -170,54 +169,55 @@ public class MiscControllerTest extends AbstractTransformerControllerTest } MvcResult result = sendText("txt", - "MacDingbat", - MIMETYPE_TEXT_PLAIN, - "txt", - MIMETYPE_TEXT_PLAIN, - "UTF-8", - content); + "MacDingbat", + MIMETYPE_TEXT_PLAIN, + "txt", + MIMETYPE_TEXT_PLAIN, + "UTF-8", + content); - String contentResult = new String(result.getResponse().getContentAsByteArray(), targetEncoding); - assertTrue("The content did not include \""+expected, contentResult.contains(expected)); + String contentResult = new String(result.getResponse().getContentAsByteArray(), + targetEncoding); + assertTrue("The content did not include \"" + expected, contentResult.contains(expected)); } @Test public void testEmptyTextFileReturnsEmptyFile() throws Exception { // Use empty content to create an empty source file - byte[] content = new byte[0]; + byte[] content = new byte[0]; MvcResult result = sendText("txt", - "UTF-8", - MIMETYPE_TEXT_PLAIN, - "txt", - MIMETYPE_TEXT_PLAIN, - "UTF-8", - content); + "UTF-8", + MIMETYPE_TEXT_PLAIN, + "txt", + MIMETYPE_TEXT_PLAIN, + "UTF-8", + content); - assertEquals("Returned content should be empty for an empty source file", 0, result.getResponse().getContentLength()); + assertEquals("Returned content should be empty for an empty source file", 0, + result.getResponse().getContentLength()); } @Test public void textToPdf() throws Exception { StringBuilder sb = new StringBuilder(); - String expected = null; - for (int i=1; i<=5; i++) + for (int i = 1; i <= 5; i++) { sb.append(i); sb.append(" I must not talk in class or feed my homework to my cat.\n"); } sb.append("\nBart\n"); - expected = sb.toString(); + String expected = sb.toString(); MvcResult result = sendText("txt", - "UTF-8", - MIMETYPE_TEXT_PLAIN, - "pdf", - MIMETYPE_PDF, - "UTF-8", - expected.getBytes()); + "UTF-8", + MIMETYPE_TEXT_PLAIN, + "pdf", + MIMETYPE_PDF, + "UTF-8", + expected.getBytes()); // Read back in the PDF and check it PDDocument doc = PDDocument.load(result.getResponse().getContentAsByteArray()); @@ -257,46 +257,54 @@ public class MiscControllerTest extends AbstractTransformerControllerTest imageBasedTransform("docx", MIMETYPE_OPENXML_WORDPROCESSING, MIMETYPE_IMAGE_JPEG, "jpeg"); } - private void imageBasedTransform(String sourceExtension, String sourceMimetype, String targetMimetype, String targetExtension) throws Exception + private void imageBasedTransform(String sourceExtension, String sourceMimetype, + String targetMimetype, String targetExtension) throws Exception { - MockMultipartFile sourceFilex = new MockMultipartFile("file", "test_file." + sourceExtension, sourceMimetype, readTestFile(sourceExtension)); + MockMultipartFile sourceFilex = new MockMultipartFile("file", + "test_file." + sourceExtension, sourceMimetype, readTestFile(sourceExtension)); - MockHttpServletRequestBuilder requestBuilder = super.mockMvcRequest("/transform", sourceFilex) - .param("targetExtension", "jpeg") - .param("targetMimetype", targetMimetype) - .param("sourceMimetype", sourceMimetype); + MockHttpServletRequestBuilder requestBuilder = super + .mockMvcRequest("/transform", sourceFilex) + .param("targetExtension", "jpeg") + .param("targetMimetype", targetMimetype) + .param("sourceMimetype", + sourceMimetype); - MvcResult result = mockMvc.perform(requestBuilder) - .andExpect(status().is(OK.value())) - .andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''test_file." + targetExtension)) - .andReturn(); - assertTrue("Expected image content but content is empty.",result.getResponse().getContentLengthLong() > 0L); + MvcResult result = mockMvc + .perform(requestBuilder) + .andExpect(status().is(OK.value())) + .andExpect(header().string("Content-Disposition", + "attachment; filename*= UTF-8''test_file." + targetExtension)) + .andReturn(); + assertTrue("Expected image content but content is empty.", + result.getResponse().getContentLengthLong() > 0L); } - private MvcResult sendText(String sourceExtension, - String sourceEncoding, - String sourceMimetype, - String targetExtension, - String targetMimetype, - String targetEncoding, - byte[] content) throws Exception + String sourceEncoding, + String sourceMimetype, + String targetExtension, + String targetMimetype, + String targetEncoding, + byte[] content) throws Exception { - MockMultipartFile sourceFilex = new MockMultipartFile("file", "test_file." + sourceExtension, sourceMimetype, content); + MockMultipartFile sourceFilex = new MockMultipartFile("file", + "test_file." + sourceExtension, sourceMimetype, content); - MockHttpServletRequestBuilder requestBuilder = super.mockMvcRequest("/transform", sourceFilex) - .param("targetExtension", targetExtension) - .param("targetEncoding", targetEncoding) - .param("targetMimetype", targetMimetype) - .param("sourceEncoding", sourceEncoding) - .param("sourceMimetype", sourceMimetype); + MockHttpServletRequestBuilder requestBuilder = super + .mockMvcRequest("/transform", sourceFilex) + .param("targetExtension", targetExtension) + .param("targetEncoding", targetEncoding) + .param("targetMimetype", targetMimetype) + .param("sourceEncoding", sourceEncoding) + .param("sourceMimetype", sourceMimetype); - - MvcResult result = mockMvc.perform(requestBuilder) - .andExpect(status().is(OK.value())) - .andExpect(header().string("Content-Disposition", "attachment; filename*= "+targetEncoding+"''test_file." + targetExtension)). - andReturn(); - return result; + return mockMvc + .perform(requestBuilder) + .andExpect(status().is(OK.value())) + .andExpect(header().string("Content-Disposition", + "attachment; filename*= " + targetEncoding + "''test_file." + targetExtension)) + .andReturn(); } private String clean(String text) @@ -307,5 +315,4 @@ public class MiscControllerTest extends AbstractTransformerControllerTest text = text.replaceAll("\\n", ""); return text; } - } \ No newline at end of file diff --git a/alfresco-docker-transform-misc/src/test/java/org/alfresco/transformer/MiscQueueTransformServiceIT.java b/alfresco-docker-transform-misc/src/test/java/org/alfresco/transformer/MiscQueueTransformServiceIT.java index 149a8f28..ed883dd8 100644 --- a/alfresco-docker-transform-misc/src/test/java/org/alfresco/transformer/MiscQueueTransformServiceIT.java +++ b/alfresco-docker-transform-misc/src/test/java/org/alfresco/transformer/MiscQueueTransformServiceIT.java @@ -26,16 +26,16 @@ */ package org.alfresco.transformer; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_HTML; +import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_TEXT_PLAIN; + +import java.util.UUID; + import org.alfresco.transform.client.model.TransformRequest; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; -import java.util.UUID; - -import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_HTML; -import static org.alfresco.transform.client.model.Mimetype.MIMETYPE_TEXT_PLAIN; - @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {"activemq.url=nio://localhost:61616"}) @@ -44,14 +44,15 @@ public class MiscQueueTransformServiceIT extends AbstractQueueTransformServiceIT @Override protected TransformRequest buildRequest() { - return TransformRequest.builder() - .withRequestId(UUID.randomUUID().toString()) - .withSourceMediaType(MIMETYPE_HTML) - .withTargetMediaType(MIMETYPE_TEXT_PLAIN) - .withTargetExtension("txt") - .withSchema(1) - .withClientData("ACS") - .withSourceReference(UUID.randomUUID().toString()) - .withSourceSize(32L).build(); + return TransformRequest + .builder() + .withRequestId(UUID.randomUUID().toString()) + .withSourceMediaType(MIMETYPE_HTML) + .withTargetMediaType(MIMETYPE_TEXT_PLAIN) + .withTargetExtension("txt") + .withSchema(1) + .withClientData("ACS") + .withSourceReference(UUID.randomUUID().toString()) + .withSourceSize(32L).build(); } } diff --git a/alfresco-docker-transform-misc/src/test/java/org/alfresco/transformer/transformers/HtmlParserContentTransformerTest.java b/alfresco-docker-transform-misc/src/test/java/org/alfresco/transformer/transformers/HtmlParserContentTransformerTest.java index 0bab9bf8..08c4ef12 100644 --- a/alfresco-docker-transform-misc/src/test/java/org/alfresco/transformer/transformers/HtmlParserContentTransformerTest.java +++ b/alfresco-docker-transform-misc/src/test/java/org/alfresco/transformer/transformers/HtmlParserContentTransformerTest.java @@ -26,13 +26,8 @@ */ package org.alfresco.transformer.transformers; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.junit4.SpringRunner; +import static org.alfresco.transformer.transformers.StringExtractingContentTransformer.SOURCE_ENCODING; +import static org.junit.Assert.assertEquals; import java.io.File; import java.io.FileOutputStream; @@ -41,9 +36,11 @@ import java.nio.file.Files; import java.util.HashMap; import java.util.Map; -import static org.alfresco.transformer.transformers.StringExtractingContentTransformer.SOURCE_ENCODING; -import static org.alfresco.transformer.transformers.StringExtractingContentTransformer.TARGET_ENCODING; -import static org.junit.Assert.*; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @Import(HtmlParserContentTransformer.class) @@ -54,24 +51,24 @@ public class HtmlParserContentTransformerTest /** * Checks that we correctly handle text in different encodings, - * no matter if the encoding is specified on the Content Property - * or in a meta tag within the HTML itself. (ALF-10466) + * no matter if the encoding is specified on the Content Property + * or in a meta tag within the HTML itself. (ALF-10466) * - * On Windows, org.htmlparser.beans.StringBean.carriageReturn() appends a new system dependent new line - * so we must be careful when checking the returned text + * On Windows, org.htmlparser.beans.StringBean.carriageReturn() appends a new system dependent new line + * so we must be careful when checking the returned text */ @Test public void testEncodingHandling() throws Exception { - final String NEWLINE = System.getProperty ("line.separator"); + final String NEWLINE = System.getProperty("line.separator"); final String TITLE = "Testing!"; final String TEXT_P1 = "This is some text in English"; final String TEXT_P2 = "This is more text in English"; final String TEXT_P3 = "C'est en Fran\u00e7ais et Espa\u00f1ol"; String partA = "" + TITLE + "" + NEWLINE; String partB = "

" + TEXT_P1 + "

" + NEWLINE + - "

" + TEXT_P2 + "

" + NEWLINE + - "

" + TEXT_P3 + "

" + NEWLINE; + "

" + TEXT_P2 + "

" + NEWLINE + + "

" + TEXT_P3 + "

" + NEWLINE; String partC = ""; final String expected = TITLE + NEWLINE + TEXT_P1 + NEWLINE + TEXT_P2 + NEWLINE + TEXT_P3 + NEWLINE; @@ -82,7 +79,7 @@ public class HtmlParserContentTransformerTest { // Content set to ISO 8859-1 tmpS = File.createTempFile("AlfrescoTestSource_", ".html"); - writeToFile(tmpS, partA+partB+partC, "ISO-8859-1"); + writeToFile(tmpS, partA + partB + partC, "ISO-8859-1"); tmpD = File.createTempFile("AlfrescoTestTarget_", ".txt"); @@ -96,7 +93,7 @@ public class HtmlParserContentTransformerTest // Content set to UTF-8 tmpS = File.createTempFile("AlfrescoTestSource_", ".html"); - writeToFile(tmpS, partA+partB+partC, "UTF-8"); + writeToFile(tmpS, partA + partB + partC, "UTF-8"); tmpD = File.createTempFile("AlfrescoTestTarget_", ".txt"); parameters = new HashMap<>(); @@ -106,10 +103,9 @@ public class HtmlParserContentTransformerTest tmpS.delete(); tmpD.delete(); - // Content set to UTF-16 tmpS = File.createTempFile("AlfrescoTestSource_", ".html"); - writeToFile(tmpS, partA+partB+partC, "UTF-16"); + writeToFile(tmpS, partA + partB + partC, "UTF-16"); tmpD = File.createTempFile("AlfrescoTestTarget_", ".txt"); parameters = new HashMap<>(); @@ -129,9 +125,9 @@ public class HtmlParserContentTransformerTest // Content set to ISO 8859-1, meta set to UTF-8 tmpS = File.createTempFile("AlfrescoTestSource_", ".html"); - String str = partA+ - "" + - partB+partC; + String str = partA + + "" + + partB + partC; writeToFile(tmpS, str, "UTF-8"); @@ -144,7 +140,6 @@ public class HtmlParserContentTransformerTest tmpS.delete(); tmpD.delete(); - // Note - we can't test UTF-16 with only a meta encoding, // because without that the parser won't know about the // 2 byte format so won't be able to identify the meta tag @@ -164,10 +159,8 @@ public class HtmlParserContentTransformerTest } } - private String readFromFile(File file, String encoding) throws Exception + private String readFromFile(File file, final String encoding) throws Exception { - String content = "wrong content"; - content = new String(Files.readAllBytes(file.toPath()), encoding); - return content; + return new String(Files.readAllBytes(file.toPath()), encoding); } } \ No newline at end of file diff --git a/alfresco-docker-transform-misc/src/test/java/org/alfresco/transformer/transformers/TextToPdfContentTransformerTest.java b/alfresco-docker-transform-misc/src/test/java/org/alfresco/transformer/transformers/TextToPdfContentTransformerTest.java index 3623628c..fdd15bb5 100644 --- a/alfresco-docker-transform-misc/src/test/java/org/alfresco/transformer/transformers/TextToPdfContentTransformerTest.java +++ b/alfresco-docker-transform-misc/src/test/java/org/alfresco/transformer/transformers/TextToPdfContentTransformerTest.java @@ -26,15 +26,8 @@ */ package org.alfresco.transformer.transformers; -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.text.PDFTextStripper; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.junit4.SpringRunner; +import static org.alfresco.transformer.transformers.TextToPdfContentTransformer.PAGE_LIMIT; +import static org.junit.Assert.assertEquals; import java.io.File; import java.io.FileOutputStream; @@ -43,8 +36,14 @@ import java.io.StringWriter; import java.util.HashMap; import java.util.Map; -import static org.alfresco.transformer.transformers.TextToPdfContentTransformer.PAGE_LIMIT; -import static org.junit.Assert.*; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.text.PDFTextStripper; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @Import(TextToPdfContentTransformer.class) @@ -60,7 +59,6 @@ public class TextToPdfContentTransformerTest transformer.setFontSize(20); } - @Test public void testUnlimitedPages() throws Exception { @@ -88,11 +86,11 @@ public class TextToPdfContentTransformerTest private void transformTextAndCheckPageLength(int pageLimit) throws Exception { int pageLength = 32; - int lines = (pageLength+10) * ((pageLimit > 0) ? pageLimit : 1); + int lines = (pageLength + 10) * ((pageLimit > 0) ? pageLimit : 1); StringBuilder sb = new StringBuilder(); String checkText = null; int cutoff = pageLimit * pageLength; - for (int i=1; i<=lines; i++) + for (int i = 1; i <= lines; i++) { sb.append(i); sb.append(" I must not talk in class or feed my homework to my cat.\n"); @@ -105,12 +103,12 @@ public class TextToPdfContentTransformerTest transformTextAndCheck(text, "UTF-8", checkText, String.valueOf(pageLimit)); } - private void transformTextAndCheck(String text, String encoding, String checkText, String pageLimit) throws Exception + private void transformTextAndCheck(String text, String encoding, String checkText, + String pageLimit) throws Exception { // Get a reader for the text File sourceFile = File.createTempFile("AlfrescoTestSource_", ".txt"); - writeToFile(sourceFile,text, encoding); - + writeToFile(sourceFile, text, encoding); // And a temp writer File targetFile = File.createTempFile("AlfrescoTestTarget_", ".pdf"); @@ -130,8 +128,8 @@ public class TextToPdfContentTransformerTest String roundTrip = clean(textWriter.toString()); assertEquals( - "Incorrect text in PDF when starting from text in " + encoding, - checkText, roundTrip + "Incorrect text in PDF when starting from text in " + encoding, + checkText, roundTrip ); sourceFile.delete(); diff --git a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/AbstractTransformerController.java b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/AbstractTransformerController.java index 46b048ad..aff695fd 100644 --- a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/AbstractTransformerController.java +++ b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/AbstractTransformerController.java @@ -26,20 +26,22 @@ */ package org.alfresco.transformer; +import static java.util.stream.Collectors.joining; import static org.alfresco.transformer.fs.FileManager.buildFile; import static org.alfresco.transformer.fs.FileManager.createTargetFileName; import static org.alfresco.transformer.fs.FileManager.deleteFile; import static org.alfresco.transformer.fs.FileManager.getFilenameFromContentDisposition; import static org.alfresco.transformer.fs.FileManager.save; import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.CREATED; import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; import static org.springframework.http.HttpStatus.OK; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; +import static org.springframework.util.StringUtils.getFilenameExtension; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.util.stream.Collectors; import org.alfresco.transform.client.model.TransformReply; import org.alfresco.transform.client.model.TransformRequest; @@ -59,7 +61,6 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.util.StringUtils; import org.springframework.validation.DirectFieldBindingResult; import org.springframework.validation.Errors; import org.springframework.web.bind.annotation.GetMapping; @@ -76,32 +77,34 @@ import com.fasterxml.jackson.databind.ObjectMapper; * *

Status Codes:

*
    - *
  • 200 Success
  • - *
  • 400 Bad Request: Request parameter is missing (missing mandatory parameter)
  • - *
  • 400 Bad Request: Request parameter is of the wrong type
  • - *
  • 400 Bad Request: Transformer exit code was not 0 (possible problem with the source file)
  • - *
  • 400 Bad Request: The source filename was not supplied
  • - *
  • 500 Internal Server Error: (no message with low level IO problems)
  • - *
  • 500 Internal Server Error: The target filename was not supplied (should not happen as targetExtension is checked)
  • - *
  • 500 Internal Server Error: Transformer version check exit code was not 0
  • - *
  • 500 Internal Server Error: Transformer version check failed to create any output
  • - *
  • 500 Internal Server Error: Could not read the target file
  • - *
  • 500 Internal Server Error: The target filename was malformed (should not happen because of other checks)
  • - *
  • 500 Internal Server Error: Transformer failed to create an output file (the exit code was 0, so there should be some content)
  • - *
  • 500 Internal Server Error: Filename encoding error
  • - *
  • 507 Insufficient Storage: Failed to store the source file
  • + *
  • 200 Success
  • + *
  • 400 Bad Request: Request parameter is missing (missing mandatory parameter)
  • + *
  • 400 Bad Request: Request parameter is of the wrong type
  • + *
  • 400 Bad Request: Transformer exit code was not 0 (possible problem with the source file)
  • + *
  • 400 Bad Request: The source filename was not supplied
  • + *
  • 500 Internal Server Error: (no message with low level IO problems)
  • + *
  • 500 Internal Server Error: The target filename was not supplied (should not happen as targetExtension is checked)
  • + *
  • 500 Internal Server Error: Transformer version check exit code was not 0
  • + *
  • 500 Internal Server Error: Transformer version check failed to create any output
  • + *
  • 500 Internal Server Error: Could not read the target file
  • + *
  • 500 Internal Server Error: The target filename was malformed (should not happen because of other checks)
  • + *
  • 500 Internal Server Error: Transformer failed to create an output file (the exit code was 0, so there should be some content)
  • + *
  • 500 Internal Server Error: Filename encoding error
  • + *
  • 507 Insufficient Storage: Failed to store the source file
  • * - *
  • 408 Request Timeout -- TODO implement general timeout mechanism rather than depend on transformer timeout - * (might be possible for external processes)
  • - *
  • 415 Unsupported Media Type -- TODO possibly implement a check on supported source and target mimetypes (probably not)
  • - *
  • 429 Too Many Requests: Returned by liveness probe
  • + *
  • 408 Request Timeout -- TODO implement general timeout mechanism rather than depend on transformer timeout + * (might be possible for external processes)
  • + *
  • 415 Unsupported Media Type -- TODO possibly implement a check on supported source and target mimetypes (probably not)
  • + *
  • 429 Too Many Requests: Returned by liveness probe
  • *
*

Provides methods to help super classes perform /transform requests. Also responses to /version, /ready and /live * requests.

*/ public abstract class AbstractTransformerController implements TransformController { - private static final Logger logger = LoggerFactory.getLogger(AbstractTransformerController.class); + private static final Logger logger = LoggerFactory.getLogger( + AbstractTransformerController.class); + private static String ENGINE_CONFIG = "engine_config.json"; @Autowired @@ -160,9 +163,12 @@ public abstract class AbstractTransformerController implements TransformControll final Errors errors = validateTransformRequest(request); if (!errors.getAllErrors().isEmpty()) { - reply.setStatus(HttpStatus.BAD_REQUEST.value()); - reply.setErrorDetails(errors.getAllErrors().stream().map(Object::toString) - .collect(Collectors.joining(", "))); + reply.setStatus(BAD_REQUEST.value()); + reply.setErrorDetails(errors + .getAllErrors() + .stream() + .map(Object::toString) + .collect(joining(", "))); logger.error("Invalid request, sending {}", reply); return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus())); @@ -246,8 +252,8 @@ public abstract class AbstractTransformerController implements TransformControll reply.setStatus(e.getStatusCode().value()); reply.setErrorDetails(messageWithCause("Failed at writing the transformed file. ", e)); - logger.error("Failed to save target file (HttpClientErrorException), sending {}" + - reply, e); + logger.error("Failed to save target file (HttpClientErrorException), sending " + reply, + e); return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus())); } catch (Exception e) @@ -278,9 +284,9 @@ public abstract class AbstractTransformerController implements TransformControll } reply.setTargetReference(targetRef.getEntry().getFileRef()); - reply.setStatus(HttpStatus.CREATED.value()); + reply.setStatus(CREATED.value()); - logger.info("Sending successful {}, timeout {} ms", reply); + logger.info("Sending successful {}, timeout {} ms", reply, timeout); return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus())); } @@ -297,7 +303,7 @@ public abstract class AbstractTransformerController implements TransformControll * @param sourceReference reference to the file in Alfresco Shared File Store * @return the file containing the source content for the transformation */ - private File loadSourceFile(final String sourceReference) throws Exception + private File loadSourceFile(final String sourceReference) { ResponseEntity responseEntity = alfrescoSharedFileStoreClient .retrieveFile(sourceReference); @@ -306,7 +312,7 @@ public abstract class AbstractTransformerController implements TransformControll HttpHeaders headers = responseEntity.getHeaders(); String filename = getFilenameFromContentDisposition(headers); - String extension = StringUtils.getFilenameExtension(filename); + String extension = getFilenameExtension(filename); MediaType contentType = headers.getContentType(); long size = headers.getContentLength(); @@ -314,7 +320,7 @@ public abstract class AbstractTransformerController implements TransformControll if (body == null) { String message = "Source file with reference: " + sourceReference + " is null or empty. " - + "Transformation will fail and stop now as there is no content to be transformed."; + + "Transformation will fail and stop now as there is no content to be transformed."; logger.warn(message); throw new TransformException(BAD_REQUEST.value(), message); } @@ -322,7 +328,7 @@ public abstract class AbstractTransformerController implements TransformControll logger.debug("Read source content {} length={} contentType={}", sourceReference, size, contentType); - + save(body, file); LogEntry.setSource(filename, size); return file; diff --git a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/QueueTransformService.java b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/QueueTransformService.java index e00e7e12..7cffd7dc 100644 --- a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/QueueTransformService.java +++ b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/QueueTransformService.java @@ -26,6 +26,11 @@ */ package org.alfresco.transformer; +import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; + +import java.util.Optional; + import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.Message; @@ -44,8 +49,6 @@ import org.springframework.jms.annotation.JmsListener; import org.springframework.jms.support.converter.MessageConversionException; import org.springframework.stereotype.Component; -import java.util.Optional; - /** * Queue Transformer service. * This service reads all the requests for the particular engine, forwards them to the worker @@ -56,12 +59,11 @@ import java.util.Optional; * created on 18/12/2018 */ @Component -@ConditionalOnProperty(name="activemq.url") +@ConditionalOnProperty(name = "activemq.url") public class QueueTransformService { private static final Logger logger = LoggerFactory.getLogger(QueueTransformService.class); - // TODO: I know this is not smart but all the the transformation logic is in the Controller. // The controller also manages the probes. There's tons of refactoring needed there, hence this. Sorry. @Autowired @@ -98,7 +100,9 @@ public class QueueTransformService } catch (JMSException e) { - logger.error("Cannot find 'replyTo' destination queue for message with correlationID {}. Stopping. ", correlationId); + logger.error( + "Cannot find 'replyTo' destination queue for message with correlationID {}. Stopping. ", + correlationId); return; } @@ -126,7 +130,7 @@ public class QueueTransformService } TransformReply reply = transformController.transform(transformRequest.get(), null) - .getBody(); + .getBody(); transformReplySender.send(replyToDestinationQueue, reply); } @@ -150,36 +154,39 @@ public class QueueTransformService { String message = "MessageConversionException during T-Request deserialization of message with correlationID " - + correlationId + ": "; - throw new TransformException(HttpStatus.BAD_REQUEST.value(), message + e.getMessage()); + + correlationId + ": "; + throw new TransformException(BAD_REQUEST.value(), message + e.getMessage()); } catch (JMSException e) { String message = "JMSException during T-Request deserialization of message with correlationID " - + correlationId + ": "; - throw new TransformException(HttpStatus.INTERNAL_SERVER_ERROR.value(), + + correlationId + ": "; + throw new TransformException(INTERNAL_SERVER_ERROR.value(), message + e.getMessage()); } catch (Exception e) { String message = "Exception during T-Request deserialization of message with correlationID " - + correlationId + ": "; - throw new TransformException(HttpStatus.INTERNAL_SERVER_ERROR.value(), + + correlationId + ": "; + throw new TransformException(INTERNAL_SERVER_ERROR.value(), message + e.getMessage()); } } - private void replyWithInternalSvErr(final Destination destination, final String msg, final String correlationId) - { - replyWithError(destination, HttpStatus.INTERNAL_SERVER_ERROR, msg, correlationId); - } - - private void replyWithError(final Destination destination, final HttpStatus status, final String msg, + private void replyWithInternalSvErr(final Destination destination, final String msg, final String correlationId) { - final TransformReply reply = TransformReply.builder() + replyWithError(destination, INTERNAL_SERVER_ERROR, msg, correlationId); + } + + private void replyWithError(final Destination destination, final HttpStatus status, + final String msg, + final String correlationId) + { + final TransformReply reply = TransformReply + .builder() .withStatus(status.value()) .withErrorDetails(msg) .build(); diff --git a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/TransformInterceptor.java b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/TransformInterceptor.java index 08516f61..ffe2de79 100644 --- a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/TransformInterceptor.java +++ b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/TransformInterceptor.java @@ -53,7 +53,7 @@ public class TransformInterceptor extends HandlerInterceptorAdapter @Override public void afterCompletion(HttpServletRequest request, - HttpServletResponse response, Object handler, Exception ex) + HttpServletResponse response, Object handler, Exception ex) { // TargetFile cannot be deleted until completion, otherwise 0 bytes are sent. deleteFile(request, SOURCE_FILE); diff --git a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/clients/AlfrescoSharedFileStoreClient.java b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/clients/AlfrescoSharedFileStoreClient.java index 9c93f2ac..025f9bd3 100644 --- a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/clients/AlfrescoSharedFileStoreClient.java +++ b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/clients/AlfrescoSharedFileStoreClient.java @@ -26,6 +26,9 @@ */ package org.alfresco.transformer.clients; +import static org.springframework.http.HttpMethod.POST; +import static org.springframework.http.MediaType.MULTIPART_FORM_DATA; + import java.io.File; import org.alfresco.transform.exceptions.TransformException; @@ -36,8 +39,6 @@ import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.util.LinkedMultiValueMap; import org.springframework.web.client.HttpClientErrorException; @@ -87,11 +88,11 @@ public class AlfrescoSharedFileStoreClient LinkedMultiValueMap map = new LinkedMultiValueMap<>(); map.add("file", value); HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.MULTIPART_FORM_DATA); + headers.setContentType(MULTIPART_FORM_DATA); HttpEntity> requestEntity = new HttpEntity<>(map, headers); ResponseEntity responseEntity = restTemplate - .exchange(fileStoreUrl, HttpMethod.POST, requestEntity, FileRefResponse.class); + .exchange(fileStoreUrl, POST, requestEntity, FileRefResponse.class); return responseEntity.getBody(); } catch (HttpClientErrorException e) diff --git a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/config/WebApplicationConfig.java b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/config/WebApplicationConfig.java index 3efa00b3..1d6f7ab1 100644 --- a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/config/WebApplicationConfig.java +++ b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/config/WebApplicationConfig.java @@ -26,12 +26,12 @@ */ package org.alfresco.transformer.config; +import org.alfresco.transform.client.model.TransformRequestValidator; import org.alfresco.transformer.TransformInterceptor; import org.alfresco.transformer.clients.AlfrescoSharedFileStoreClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; -import org.alfresco.transform.client.model.TransformRequestValidator; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -40,16 +40,18 @@ public class WebApplicationConfig implements WebMvcConfigurer { @Override - public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(transformInterceptor()).addPathPatterns("/transform", "/live", "/ready"); + public void addInterceptors(InterceptorRegistry registry) + { + registry.addInterceptor(transformInterceptor()).addPathPatterns("/transform", "/live", + "/ready"); } @Bean - public TransformInterceptor transformInterceptor() { + public TransformInterceptor transformInterceptor() + { return new TransformInterceptor(); } - @Bean public RestTemplate restTemplate() { @@ -57,7 +59,8 @@ public class WebApplicationConfig implements WebMvcConfigurer } @Bean - public AlfrescoSharedFileStoreClient alfrescoSharedFileStoreClient(){ + public AlfrescoSharedFileStoreClient alfrescoSharedFileStoreClient() + { return new AlfrescoSharedFileStoreClient(); } diff --git a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/executors/AbstractCommandExecutor.java b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/executors/AbstractCommandExecutor.java index 81610a64..b4c04f2f 100644 --- a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/executors/AbstractCommandExecutor.java +++ b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/executors/AbstractCommandExecutor.java @@ -37,12 +37,13 @@ import org.alfresco.util.exec.RuntimeExec; import org.alfresco.util.exec.RuntimeExec.ExecutionResult; /** + * */ public abstract class AbstractCommandExecutor implements CommandExecutor { private final RuntimeExec transformCommand = createTransformCommand(); private final RuntimeExec checkCommand = createCheckCommand(); - + protected abstract RuntimeExec createTransformCommand(); protected abstract RuntimeExec createCheckCommand(); diff --git a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/executors/CommandExecutor.java b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/executors/CommandExecutor.java index 9da4e1a9..2918d860 100644 --- a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/executors/CommandExecutor.java +++ b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/executors/CommandExecutor.java @@ -34,7 +34,7 @@ import org.alfresco.transformer.logging.LogEntry; /** * Basic interface for executing transformations via Shell commands - * + * * @author Cezar Leahu */ public interface CommandExecutor diff --git a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/executors/JavaExecutor.java b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/executors/JavaExecutor.java index 190486a7..43f3a717 100644 --- a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/executors/JavaExecutor.java +++ b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/executors/JavaExecutor.java @@ -32,7 +32,7 @@ import org.alfresco.transform.exceptions.TransformException; /** * Basic interface for executing transformations inside Java/JVM - * + * * @author Cezar Leahu */ public interface JavaExecutor diff --git a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/fs/FileManager.java b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/fs/FileManager.java index beacc873..ba27fc05 100644 --- a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/fs/FileManager.java +++ b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/fs/FileManager.java @@ -26,9 +26,12 @@ */ package org.alfresco.transformer.fs; +import static org.springframework.http.HttpHeaders.CONTENT_DISPOSITION; import static org.springframework.http.HttpStatus.BAD_REQUEST; import static org.springframework.http.HttpStatus.INSUFFICIENT_STORAGE; import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; +import static org.springframework.util.StringUtils.getFilename; +import static org.springframework.util.StringUtils.getFilenameExtension; import java.io.File; import java.io.IOException; @@ -46,11 +49,11 @@ import org.springframework.core.io.Resource; import org.springframework.core.io.UrlResource; import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; -import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.util.UriUtils; /** + * */ public class FileManager { @@ -76,7 +79,7 @@ public class FileManager public static File buildFile(String filename) { - filename = checkFilename( false, filename); + filename = checkFilename(false, filename); LogEntry.setTarget(filename); return TempFileProvider.createTempFile("target_", "_" + filename); } @@ -98,12 +101,13 @@ public class FileManager */ private static String checkFilename(boolean source, String filename) { - filename = StringUtils.getFilename(filename); + filename = getFilename(filename); if (filename == null || filename.isEmpty()) { String sourceOrTarget = source ? "source" : "target"; int statusCode = source ? BAD_REQUEST.value() : INTERNAL_SERVER_ERROR.value(); - throw new TransformException(statusCode, "The " + sourceOrTarget + " filename was not supplied"); + throw new TransformException(statusCode, + "The " + sourceOrTarget + " filename was not supplied"); } return filename; } @@ -112,7 +116,8 @@ public class FileManager { try { - Files.copy(multipartFile.getInputStream(), file.toPath(), StandardCopyOption.REPLACE_EXISTING); + Files.copy(multipartFile.getInputStream(), file.toPath(), + StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { @@ -129,7 +134,8 @@ public class FileManager } catch (IOException e) { - throw new TransformException(INSUFFICIENT_STORAGE.value(), "Failed to store the source file", e); + throw new TransformException(INSUFFICIENT_STORAGE.value(), + "Failed to store the source file", e); } } @@ -158,7 +164,7 @@ public class FileManager public static String getFilenameFromContentDisposition(HttpHeaders headers) { String filename = ""; - String contentDisposition = headers.getFirst(HttpHeaders.CONTENT_DISPOSITION); + String contentDisposition = headers.getFirst(CONTENT_DISPOSITION); if (contentDisposition != null) { String[] strings = contentDisposition.split("; *"); @@ -171,28 +177,31 @@ public class FileManager return filename; } - /** * Returns the file name for the target file * - * @param fileName Desired file name + * @param fileName Desired file name * @param targetExtension File extension * @return Target file name */ - public static String createTargetFileName(String fileName, String targetExtension) + public static String createTargetFileName(final String fileName, final String targetExtension) { - String targetFilename = null; - String sourceFilename = fileName; - sourceFilename = StringUtils.getFilename(sourceFilename); - if (sourceFilename != null && !sourceFilename.isEmpty()) + final String sourceFilename = getFilename(fileName); + + if (sourceFilename == null || sourceFilename.isEmpty()) { - String ext = StringUtils.getFilenameExtension(sourceFilename); - targetFilename = (ext != null && !ext.isEmpty() - ? sourceFilename.substring(0, sourceFilename.length()-ext.length()-1) - : sourceFilename)+ - '.'+targetExtension; + return null; } - return targetFilename; + + final String ext = getFilenameExtension(sourceFilename); + + if (ext == null || ext.isEmpty()) + { + return sourceFilename + '.' + targetExtension; + } + + return sourceFilename.substring(0, sourceFilename.length() - ext.length() - 1) + + '.' + targetExtension; } /** @@ -207,7 +216,7 @@ public class FileManager { String filename = multipartFile.getOriginalFilename(); long size = multipartFile.getSize(); - filename = checkFilename( true, filename); + filename = checkFilename(true, filename); File file = TempFileProvider.createTempFile("source_", "_" + filename); request.setAttribute(SOURCE_FILE, file); save(multipartFile, file); @@ -228,9 +237,8 @@ public class FileManager targetFile) { Resource targetResource = load(targetFile); - targetFilename = UriUtils.encodePath(StringUtils.getFilename(targetFilename), "UTF-8"); - return ResponseEntity.ok().header(HttpHeaders - .CONTENT_DISPOSITION, + targetFilename = UriUtils.encodePath(getFilename(targetFilename), "UTF-8"); + return ResponseEntity.ok().header(CONTENT_DISPOSITION, "attachment; filename*= UTF-8''" + targetFilename).body(targetResource); } } diff --git a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/logging/LogEntry.java b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/logging/LogEntry.java index fccd8882..53c60b73 100644 --- a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/logging/LogEntry.java +++ b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/logging/LogEntry.java @@ -135,7 +135,7 @@ public final class LogEntry int i = filename.lastIndexOf('.'); if (i != -1) { - filename = filename.substring(i+1); + filename = filename.substring(i + 1); } return filename; } @@ -201,7 +201,8 @@ public final class LogEntry if (logEntry.statusCode == OK.value()) { logEntry.durationStreamOut = System.currentTimeMillis() - logEntry.start - - logEntry.durationStreamIn - max(logEntry.durationTransform, 0) - max(logEntry.durationDelay, 0); + logEntry.durationStreamIn - max(logEntry.durationTransform, + 0) - max(logEntry.durationDelay, 0); } currentLogEntry.remove(); @@ -228,17 +229,19 @@ public final class LogEntry public String getDuration() { - long duration = durationStreamIn + max(durationTransform, 0) + max(durationDelay, 0) + max(durationStreamOut, 0); + long duration = durationStreamIn + max(durationTransform, 0) + max(durationDelay, 0) + max( + durationStreamOut, 0); return duration <= 5 ? "" - : time(duration)+ - " ("+ - (time(durationStreamIn)+' '+ - time(durationTransform)+' '+ - (durationDelay > 0 - ? time(durationDelay)+' '+(durationStreamOut < 0 ? "-" : time(durationStreamOut)) - : time(durationStreamOut))).trim()+ - ")"; + : time(duration) + + " (" + + (time(durationStreamIn) + ' ' + + time(durationTransform) + ' ' + + (durationDelay > 0 + ? time(durationDelay) + ' ' + (durationStreamOut < 0 ? "-" : time( + durationStreamOut)) + : time(durationStreamOut))).trim() + + ")"; } public String getSource() @@ -274,16 +277,16 @@ public final class LogEntry private String time(long ms) { return ms == -1 ? "" : size(ms, "1ms", - new String[] { "ms", "s", "min", "hr" }, - new long[] { 1000, 60*1000, 60*60*1000, Long.MAX_VALUE}); + new String[]{"ms", "s", "min", "hr"}, + new long[]{1000, 60 * 1000, 60 * 60 * 1000, Long.MAX_VALUE}); } private String size(long size) { // TODO fix numeric overflow in TB expression return size == -1 ? "" : size(size, "1 byte", - new String[] { "bytes", " KB", " MB", " GB", " TB" }, - new long[] { 1024, 1024*1024, 1024*1024*1024, 1024*1024*1024*1024, Long.MAX_VALUE }); + new String[]{"bytes", " KB", " MB", " GB", " TB"}, + new long[]{1024, 1024 * 1024, 1024 * 1024 * 1024, 1024 * 1024 * 1024 * 1024, Long.MAX_VALUE}); } private String size(long size, String singleValue, String[] units, long[] dividers) @@ -293,16 +296,16 @@ public final class LogEntry return singleValue; } long divider = 1; - for(int i = 0; i < units.length-1; i++) + for (int i = 0; i < units.length - 1; i++) { long nextDivider = dividers[i]; - if(size < nextDivider) + if (size < nextDivider) { return unitFormat(size, divider, units[i]); } divider = nextDivider; } - return unitFormat(size, divider, units[units.length-1]); + return unitFormat(size, divider, units[units.length - 1]); } private String unitFormat(long size, long divider, String unit) @@ -311,7 +314,7 @@ public final class LogEntry int decimalPoint = (int) size % 10; StringBuilder sb = new StringBuilder(); - sb.append(size/10); + sb.append(size / 10); if (decimalPoint != 0) { sb.append("."); diff --git a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/logging/StandardMessages.java b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/logging/StandardMessages.java index 2334827d..988e8b59 100644 --- a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/logging/StandardMessages.java +++ b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/logging/StandardMessages.java @@ -31,5 +31,5 @@ public interface StandardMessages String LICENCE = "License rights for this program may be obtained from Alfresco Software, Ltd. pursuant to a written agreement\n" + "and any use of this program without such an agreement is prohibited.\n" + - "\n" ; + "\n"; } diff --git a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/messaging/MessagingConfig.java b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/messaging/MessagingConfig.java index ce5d7568..181d67d4 100644 --- a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/messaging/MessagingConfig.java +++ b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/messaging/MessagingConfig.java @@ -98,7 +98,8 @@ public class MessagingConfig implements JmsListenerConfigurer @Bean @ConditionalOnProperty(name = "activemq.url") - public Queue engineRequestQueue(@Value("${queue.engineRequestQueue}") String engineRequestQueueValue) + public Queue engineRequestQueue( + @Value("${queue.engineRequestQueue}") String engineRequestQueueValue) { return new ActiveMQQueue(engineRequestQueueValue); } diff --git a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/messaging/TransformMessageConverter.java b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/messaging/TransformMessageConverter.java index 15503f3a..cad7e95e 100644 --- a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/messaging/TransformMessageConverter.java +++ b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/messaging/TransformMessageConverter.java @@ -90,13 +90,13 @@ public class TransformMessageConverter implements MessageConverter @NonNull final Object object, @NonNull final Session session) throws JMSException, MessageConversionException { - return converter.toMessage(object, session); + return converter.toMessage(object, session); } @Override @NonNull public Object fromMessage(@NonNull final Message message) throws JMSException { - return converter.fromMessage(message); + return converter.fromMessage(message); } } diff --git a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/messaging/TransformReplySender.java b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/messaging/TransformReplySender.java index 5fb85ef7..2e1e7fa2 100644 --- a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/messaging/TransformReplySender.java +++ b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/messaging/TransformReplySender.java @@ -56,7 +56,8 @@ public class TransformReplySender send(destination, reply, reply.getRequestId()); } - public void send(final Destination destination, final TransformReply reply, final String correlationId) + public void send(final Destination destination, final TransformReply reply, + final String correlationId) { try { diff --git a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/model/FileRefEntity.java b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/model/FileRefEntity.java index 34524ad5..30c9cd09 100644 --- a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/model/FileRefEntity.java +++ b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/model/FileRefEntity.java @@ -37,25 +37,19 @@ public class FileRefEntity { private String fileRef; - public FileRefEntity() - { - } + public FileRefEntity() {} public FileRefEntity(String fileRef) { this.fileRef = fileRef; } - public void setFileRef(String fileRef){ + public void setFileRef(String fileRef) + { this.fileRef = fileRef; } - public String getFileRef() - { - return fileRef; - } - @Override - public String toString() + public String getFileRef() { return fileRef; } @@ -63,16 +57,10 @@ public class FileRefEntity @Override public boolean equals(Object o) { - if (this == o) - { - return true; - } - if (o == null || getClass() != o.getClass()) - { - return false; - } - FileRefEntity fileRef = (FileRefEntity) o; - return Objects.equals(this.fileRef, fileRef.fileRef); + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + FileRefEntity that = (FileRefEntity) o; + return Objects.equals(fileRef, that.fileRef); } @Override @@ -80,4 +68,10 @@ public class FileRefEntity { return Objects.hash(fileRef); } + + @Override + public String toString() + { + return fileRef; + } } diff --git a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/model/FileRefResponse.java b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/model/FileRefResponse.java index afc5c118..819498be 100644 --- a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/model/FileRefResponse.java +++ b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/model/FileRefResponse.java @@ -35,9 +35,7 @@ public class FileRefResponse { private FileRefEntity entry; - public FileRefResponse() - { - } + public FileRefResponse() {} public FileRefResponse(FileRefEntity entry) { diff --git a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/probes/ProbeTestTransform.java b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/probes/ProbeTestTransform.java index 2f58c237..3e4b3779 100644 --- a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/probes/ProbeTestTransform.java +++ b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/probes/ProbeTestTransform.java @@ -43,8 +43,8 @@ import java.util.concurrent.atomic.AtomicLong; import javax.servlet.http.HttpServletRequest; -import org.alfresco.transformer.AbstractTransformerController; import org.alfresco.transform.exceptions.TransformException; +import org.alfresco.transformer.AbstractTransformerController; import org.alfresco.transformer.logging.LogEntry; import org.alfresco.util.TempFileProvider; import org.slf4j.Logger; @@ -65,11 +65,11 @@ import org.slf4j.LoggerFactory; * code resulting in the k8s pod being terminated, after a predefined number of transformations have been performed or * if any transformation takes a long time. These are controlled by environment variables:

*
    - *
  • livenessPercent - The percentage slower the small test transform must be to indicate there is a problem.
  • - *
  • livenessTransformPeriodSeconds - As liveness probes should be frequent, not every request should result in - * a test transformation. This value defines the gap between transformations.
  • - *
  • maxTransforms - the maximum number of transformation to be performed before a restart.
  • - *
  • maxTransformSeconds - the maximum time for a transformation, including failed ones.
  • + *
  • livenessPercent - The percentage slower the small test transform must be to indicate there is a problem.
  • + *
  • livenessTransformPeriodSeconds - As liveness probes should be frequent, not every request should result in + * a test transformation. This value defines the gap between transformations.
  • + *
  • maxTransforms - the maximum number of transformation to be performed before a restart.
  • + *
  • maxTransformSeconds - the maximum time for a transformation, including failed ones.
  • *
*/ public abstract class ProbeTestTransform @@ -111,28 +111,30 @@ public abstract class ProbeTestTransform /** * See Probes.md for more info. - * @param expectedLength was the length of the target file during testing - * @param plusOrMinus simply allows for some variation in the transformed size caused by new versions of dates - * @param livenessPercent indicates that for this type of transform a variation up to 2 and a half times is not - * unreasonable under load - * @param maxTransforms default values normally supplied by helm. Not identical so we can be sure which value is used. - * @param maxTransformSeconds default values normally supplied by helm. Not identical so we can be sure which value is used. - * @param livenessTransformPeriodSeconds default values normally supplied by helm. Not identical so we can be sure which value is used. + * + * @param expectedLength was the length of the target file during testing + * @param plusOrMinus simply allows for some variation in the transformed size caused by new versions of dates + * @param livenessPercent indicates that for this type of transform a variation up to 2 and a half times is not + * unreasonable under load + * @param maxTransforms default values normally supplied by helm. Not identical so we can be sure which value is used. + * @param maxTransformSeconds default values normally supplied by helm. Not identical so we can be sure which value is used. + * @param livenessTransformPeriodSeconds default values normally supplied by helm. Not identical so we can be sure which value is used. */ public ProbeTestTransform(AbstractTransformerController controller, - String sourceFilename, String targetFilename, long expectedLength, long plusOrMinus, - int livenessPercent, long maxTransforms, long maxTransformSeconds, - long livenessTransformPeriodSeconds) + String sourceFilename, String targetFilename, long expectedLength, long plusOrMinus, + int livenessPercent, long maxTransforms, long maxTransformSeconds, + long livenessTransformPeriodSeconds) { this.sourceFilename = sourceFilename; this.targetFilename = targetFilename; - minExpectedLength = Math.max(0, expectedLength-plusOrMinus); - maxExpectedLength = expectedLength+plusOrMinus; + minExpectedLength = Math.max(0, expectedLength - plusOrMinus); + maxExpectedLength = expectedLength + plusOrMinus; this.livenessPercent = (int) getPositiveLongEnv("livenessPercent", livenessPercent); maxTransformCount = getPositiveLongEnv("maxTransforms", maxTransforms); - maxTransformTime = getPositiveLongEnv("maxTransformSeconds", maxTransformSeconds)*1000; - livenessTransformPeriod = getPositiveLongEnv("livenessTransformPeriodSeconds", livenessTransformPeriodSeconds)*1000; + maxTransformTime = getPositiveLongEnv("maxTransformSeconds", maxTransformSeconds) * 1000; + livenessTransformPeriod = getPositiveLongEnv("livenessTransformPeriodSeconds", + livenessTransformPeriodSeconds) * 1000; livenessTransformEnabled = getBooleanEnvVar("livenessTransformEnabled", false); } @@ -182,9 +184,9 @@ public abstract class ProbeTestTransform } return (isLiveProbe && livenessTransformPeriod > 0 && (transCount <= AVERAGE_OVER_TRANSFORMS || nextTransformTime < System.currentTimeMillis())) - || !initialised.get() - ? doTransform(request, isLiveProbe) - : doNothing(isLiveProbe); + || !initialised.get() + ? doTransform(request, isLiveProbe) + : doNothing(isLiveProbe); } private String doNothing(boolean isLiveProbe) @@ -238,39 +240,39 @@ public abstract class ProbeTestTransform checkMaxTransformTimeAndCount(isLiveProbe); - return getProbeMessage(isLiveProbe)+message; + return getProbeMessage(isLiveProbe) + message; } private void checkMaxTransformTimeAndCount(boolean isLiveProbe) { if (die.get()) { - throw new TransformException(TOO_MANY_REQUESTS.value(), getMessagePrefix(isLiveProbe) + - "Transformer requested to die. A transform took longer than "+ - (maxTransformTime *1000)+" seconds"); + throw new TransformException(TOO_MANY_REQUESTS.value(), + getMessagePrefix(isLiveProbe) + "Transformer requested to die. A transform took " + + "longer than " + (maxTransformTime * 1000) + " seconds"); } if (maxTransformCount > 0 && transformCount.get() > maxTransformCount) { - throw new TransformException(TOO_MANY_REQUESTS.value(), getMessagePrefix(isLiveProbe) + - "Transformer requested to die. It has performed more than "+ - maxTransformCount+" transformations"); + throw new TransformException(TOO_MANY_REQUESTS.value(), + getMessagePrefix(isLiveProbe) + "Transformer requested to die. It has performed " + + "more than " + maxTransformCount + " transformations"); } } private File getSourceFile(HttpServletRequest request, boolean isLiveProbe) { incrementTransformerCount(); - File sourceFile = TempFileProvider.createTempFile("source_", "_"+ sourceFilename); + File sourceFile = TempFileProvider.createTempFile("source_", "_" + sourceFilename); request.setAttribute(SOURCE_FILE, sourceFile); - try (InputStream inputStream = this.getClass().getResourceAsStream('/'+sourceFilename)) + try (InputStream inputStream = this.getClass().getResourceAsStream('/' + sourceFilename)) { Files.copy(inputStream, sourceFile.toPath(), StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { - throw new TransformException(INSUFFICIENT_STORAGE.value(), getMessagePrefix(isLiveProbe)+ - "Failed to store the source file", e); + throw new TransformException(INSUFFICIENT_STORAGE.value(), + getMessagePrefix(isLiveProbe) + "Failed to store the source file", e); } long length = sourceFile.length(); LogEntry.setSource(sourceFilename, length); @@ -279,7 +281,7 @@ public abstract class ProbeTestTransform private File getTargetFile(HttpServletRequest request) { - File targetFile = TempFileProvider.createTempFile("target_", "_"+targetFilename); + File targetFile = TempFileProvider.createTempFile("target_", "_" + targetFilename); request.setAttribute(TARGET_FILE, targetFile); LogEntry.setTarget(targetFilename); return targetFile; @@ -302,13 +304,15 @@ public abstract class ProbeTestTransform String message = getMessagePrefix(isLiveProbe) + "Success - Transform " + time + "ms"; if (++transCount > 1) { - normalTime = (normalTime * (transCount-2) + time) / (transCount-1); + normalTime = (normalTime * (transCount - 2) + time) / (transCount - 1); maxTime = (normalTime * (livenessPercent + 100)) / 100; - if ((!isLiveProbe && !readySent.getAndSet(true)) || transCount > AVERAGE_OVER_TRANSFORMS) + if ((!isLiveProbe && !readySent.getAndSet( + true)) || transCount > AVERAGE_OVER_TRANSFORMS) { nextTransformTime = System.currentTimeMillis() + livenessTransformPeriod; - logger.trace("{} - {}ms+{}%={}ms", message, normalTime, livenessPercent, maxTime); + logger.trace("{} - {}ms+{}%={}ms", message, normalTime, livenessPercent, + maxTime); } } else if (!isLiveProbe && !readySent.getAndSet(true)) @@ -362,7 +366,6 @@ public abstract class ProbeTestTransform public long getNormalTime() { - return normalTime; } } diff --git a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/util/Util.java b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/util/Util.java index f1a6bd21..61631770 100644 --- a/alfresco-transformer-base/src/main/java/org/alfresco/transformer/util/Util.java +++ b/alfresco-transformer-base/src/main/java/org/alfresco/transformer/util/Util.java @@ -27,6 +27,7 @@ package org.alfresco.transformer.util; /** + * */ public class Util { @@ -49,6 +50,6 @@ public class Util */ public static Boolean stringToBoolean(String param) { - return param == null? null : Boolean.parseBoolean(param); + return param == null ? null : Boolean.parseBoolean(param); } } diff --git a/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractHttpRequestTest.java b/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractHttpRequestTest.java index 259b6992..c9d88a00 100644 --- a/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractHttpRequestTest.java +++ b/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractHttpRequestTest.java @@ -26,16 +26,20 @@ */ package org.alfresco.transformer; +import static org.junit.Assert.assertEquals; +import static org.springframework.http.HttpMethod.POST; +import static org.springframework.http.MediaType.MULTIPART_FORM_DATA; +import static org.springframework.test.util.AssertionErrors.assertTrue; + import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.web.server.LocalServerPort; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.*; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; import org.springframework.util.LinkedMultiValueMap; -import static org.junit.Assert.assertEquals; -import static org.springframework.test.util.AssertionErrors.assertTrue; - /** * Super class for testing controllers with a server. Includes tests for the AbstractTransformerController itself. * Note: Currently uses json rather than HTML as json is returned by this spring boot test harness. @@ -64,7 +68,8 @@ public abstract class AbstractHttpRequestTest @Test public void logPageExists() { - String result = restTemplate.getForObject("http://localhost:" + port + "/log", String.class); + String result = restTemplate.getForObject("http://localhost:" + port + "/log", + String.class); String title = getTransformerName() + ' ' + "Log"; assertTrue("\"" + title + "\" should be part of the page title", result.contains(title)); @@ -73,10 +78,12 @@ public abstract class AbstractHttpRequestTest @Test public void errorPageExists() { - String result = restTemplate.getForObject("http://localhost:" + port + "/error", String.class); + String result = restTemplate.getForObject("http://localhost:" + port + "/error", + String.class); String title = getTransformerName() + ' ' + "Error Page"; - assertTrue("\"" + title + "\" should be part of the page title", result.contains("Error Page")); + assertTrue("\"" + title + "\" should be part of the page title", + result.contains("Error Page")); } @Test @@ -84,7 +91,7 @@ public abstract class AbstractHttpRequestTest { // Transformer name is not part of the title as this is checked by another handler assertTransformError(false, - "Required request part 'file' is not present"); + "Required request part 'file' is not present"); } @Test @@ -96,7 +103,7 @@ public abstract class AbstractHttpRequestTest private void assertMissingParameter(String name) { assertTransformError(true, - getTransformerName() + " - Request parameter '" + name + "' is missing"); + getTransformerName() + " - Request parameter '" + name + "' is missing"); } private void assertTransformError(boolean addFile, String errorMessage) @@ -104,12 +111,15 @@ public abstract class AbstractHttpRequestTest LinkedMultiValueMap parameters = new LinkedMultiValueMap<>(); if (addFile) { - parameters.add("file", new org.springframework.core.io.ClassPathResource("quick."+getSourceExtension())); + parameters.add("file", + new org.springframework.core.io.ClassPathResource("quick." + getSourceExtension())); } HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.MULTIPART_FORM_DATA); - HttpEntity> entity = new HttpEntity<>(parameters, headers); - ResponseEntity response = restTemplate.exchange("/transform", HttpMethod.POST, entity, String.class, ""); + headers.setContentType(MULTIPART_FORM_DATA); + HttpEntity> entity = new HttpEntity<>(parameters, + headers); + ResponseEntity response = restTemplate.exchange("/transform", POST, entity, + String.class, ""); assertEquals(errorMessage, getErrorMessage(response.getBody())); } @@ -125,7 +135,7 @@ public abstract class AbstractHttpRequestTest int j = content.indexOf("\",\"path\":", i); if (j != -1) { - message = content.substring(i+11, j); + message = content.substring(i + 11, j); } } return message; diff --git a/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractQueueTransformServiceIT.java b/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractQueueTransformServiceIT.java index 2cd533db..56583a70 100644 --- a/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractQueueTransformServiceIT.java +++ b/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractQueueTransformServiceIT.java @@ -54,11 +54,12 @@ public abstract class AbstractQueueTransformServiceIT @Autowired private JmsTemplate jmsTemplate; - private final ActiveMQQueue testingQueue = new ActiveMQQueue("org.alfresco.transform.engine.IT"); + private final ActiveMQQueue testingQueue = new ActiveMQQueue( + "org.alfresco.transform.engine.IT"); @Test - public void queueTransformServiceIT() { - + public void queueTransformServiceIT() + { TransformRequest request = buildRequest(); jmsTemplate.convertAndSend(engineRequestQueue, request, m -> { diff --git a/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractTransformerControllerTest.java b/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractTransformerControllerTest.java index b1bb5f43..c59fb765 100644 --- a/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractTransformerControllerTest.java +++ b/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractTransformerControllerTest.java @@ -30,9 +30,13 @@ import static org.hamcrest.Matchers.containsString; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.springframework.http.HttpHeaders.ACCEPT; +import static org.springframework.http.HttpHeaders.CONTENT_TYPE; import static org.springframework.http.HttpStatus.BAD_REQUEST; import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; import static org.springframework.http.HttpStatus.OK; +import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -62,8 +66,6 @@ import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.core.io.ClassPathResource; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; import org.springframework.mock.web.MockMultipartFile; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.web.servlet.MockMvc; @@ -107,7 +109,8 @@ public abstract class AbstractTransformerControllerTest protected abstract AbstractTransformerController getController(); - protected abstract void updateTransformRequestWithSpecificOptions(TransformRequest transformRequest); + protected abstract void updateTransformRequestWithSpecificOptions( + TransformRequest transformRequest); /** * This method ends up being the core of the mock. @@ -151,14 +154,17 @@ public abstract class AbstractTransformerControllerTest URL testFileUrl = classLoader.getResource(testFilename); if (required && testFileUrl == null) { - throw new IOException("The test file " + testFilename + " does not exist in the resources directory"); + throw new IOException("The test file " + testFilename + + " does not exist in the resources directory"); } return testFileUrl == null ? null : new File(testFileUrl.getFile()); } - protected MockHttpServletRequestBuilder mockMvcRequest(String url, MockMultipartFile sourceFile, String... params) + protected MockHttpServletRequestBuilder mockMvcRequest(String url, MockMultipartFile sourceFile, + String... params) { - MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.multipart("/transform").file(sourceFile); + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.multipart("/transform").file( + sourceFile); if (params.length % 2 != 0) { @@ -175,20 +181,24 @@ public abstract class AbstractTransformerControllerTest @Test public void simpleTransformTest() throws Exception { - mockMvc.perform(mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension)) + mockMvc.perform( + mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension)) .andExpect(status().is(OK.value())) .andExpect(content().bytes(expectedTargetFileBytes)) - .andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''quick." + targetExtension)); + .andExpect(header().string("Content-Disposition", + "attachment; filename*= UTF-8''quick." + targetExtension)); } @Test public void testDelayTest() throws Exception { long start = System.currentTimeMillis(); - mockMvc.perform(mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension, "testDelay", "400")) + mockMvc.perform(mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension, + "testDelay", "400")) .andExpect(status().is(OK.value())) .andExpect(content().bytes(expectedTargetFileBytes)) - .andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''quick." + targetExtension)); + .andExpect(header().string("Content-Disposition", + "attachment; filename*= UTF-8''quick." + targetExtension)); long ms = System.currentTimeMillis() - start; System.out.println("Transform incluing test delay was " + ms); assertTrue("Delay sending the result back was too small " + ms, ms >= 400); @@ -206,24 +216,30 @@ public abstract class AbstractTransformerControllerTest // Looks dangerous but is okay as we only use the final filename public void dotDotSourceFilenameTest() throws Exception { - sourceFile = new MockMultipartFile("file", "../quick." + sourceExtension, sourceMimetype, expectedSourceFileBytes); + sourceFile = new MockMultipartFile("file", "../quick." + sourceExtension, sourceMimetype, + expectedSourceFileBytes); - mockMvc.perform(mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension)) + mockMvc.perform( + mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension)) .andExpect(status().is(OK.value())) .andExpect(content().bytes(expectedTargetFileBytes)) - .andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''quick." + targetExtension)); + .andExpect(header().string("Content-Disposition", + "attachment; filename*= UTF-8''quick." + targetExtension)); } @Test // Is okay, as the target filename is built up from the whole source filename and the targetExtenstion public void noExtensionSourceFilenameTest() throws Exception { - sourceFile = new MockMultipartFile("file", "../quick", sourceMimetype, expectedSourceFileBytes); + sourceFile = new MockMultipartFile("file", "../quick", sourceMimetype, + expectedSourceFileBytes); - mockMvc.perform(mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension)) + mockMvc.perform( + mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension)) .andExpect(status().is(OK.value())) .andExpect(content().bytes(expectedTargetFileBytes)) - .andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''quick." + targetExtension)); + .andExpect(header().string("Content-Disposition", + "attachment; filename*= UTF-8''quick." + targetExtension)); } @Test @@ -232,7 +248,8 @@ public abstract class AbstractTransformerControllerTest { sourceFile = new MockMultipartFile("file", "abc/", sourceMimetype, expectedSourceFileBytes); - mockMvc.perform(mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension)) + mockMvc.perform( + mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension)) .andExpect(status().is(BAD_REQUEST.value())) .andExpect(status().reason(containsString("The source filename was not supplied"))); } @@ -242,7 +259,8 @@ public abstract class AbstractTransformerControllerTest { sourceFile = new MockMultipartFile("file", "", sourceMimetype, expectedSourceFileBytes); - mockMvc.perform(mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension)) + mockMvc.perform( + mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension)) .andExpect(status().is(BAD_REQUEST.value())) .andExpect(status().reason(containsString("The source filename was not supplied"))); } @@ -252,7 +270,8 @@ public abstract class AbstractTransformerControllerTest { mockMvc.perform(mockMvcRequest("/transform", sourceFile)) .andExpect(status().is(BAD_REQUEST.value())) - .andExpect(status().reason(containsString("Request parameter 'targetExtension' is missing"))); + .andExpect(status().reason( + containsString("Request parameter 'targetExtension' is missing"))); } @Test @@ -295,13 +314,14 @@ public abstract class AbstractTransformerControllerTest String transformationReplyAsString = mockMvc .perform(MockMvcRequestBuilders .post("/transform") - .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .header(ACCEPT, APPLICATION_JSON_VALUE) + .header(CONTENT_TYPE, APPLICATION_JSON_VALUE) .content(tr)) .andExpect(status().is(BAD_REQUEST.value())) .andReturn().getResponse().getContentAsString(); - TransformReply transformReply = objectMapper.readValue(transformationReplyAsString, TransformReply.class); + TransformReply transformReply = objectMapper.readValue(transformationReplyAsString, + TransformReply.class); // Assert the reply assertEquals(BAD_REQUEST.value(), transformReply.getStatus()); @@ -317,9 +337,10 @@ public abstract class AbstractTransformerControllerTest ReflectionTestUtils .setField(AbstractTransformerController.class, "ENGINE_CONFIG", "engine_config.json"); - String response = mockMvc.perform(MockMvcRequestBuilders.get("/transform/config")) - .andExpect(status().is(OK.value())).andExpect( - header().string(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)) + String response = mockMvc + .perform(MockMvcRequestBuilders.get("/transform/config")) + .andExpect(status().is(OK.value())) + .andExpect(header().string(CONTENT_TYPE, APPLICATION_JSON_UTF8_VALUE)) .andReturn().getResponse().getContentAsString(); TransformConfig transformConfig = objectMapper.readValue(response, TransformConfig.class); @@ -335,9 +356,10 @@ public abstract class AbstractTransformerControllerTest ReflectionTestUtils.setField(AbstractTransformerController.class, "ENGINE_CONFIG", "engine_config_with_duplicates.json"); - String response = mockMvc.perform(MockMvcRequestBuilders.get("/transform/config")) - .andExpect(status().is(OK.value())).andExpect( - header().string(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)) + String response = mockMvc + .perform(MockMvcRequestBuilders.get("/transform/config")) + .andExpect(status().is(OK.value())) + .andExpect(header().string(CONTENT_TYPE, APPLICATION_JSON_UTF8_VALUE)) .andReturn().getResponse().getContentAsString(); TransformConfig transformConfig = objectMapper.readValue(response, TransformConfig.class); @@ -349,7 +371,6 @@ public abstract class AbstractTransformerControllerTest transformConfig.getTransformers().get(0).getSupportedSourceAndTargetList().size()); assertEquals(1, transformConfig.getTransformers().get(0).getTransformOptions().size()); - } @Test @@ -362,9 +383,10 @@ public abstract class AbstractTransformerControllerTest ReflectionTestUtils.setField(AbstractTransformerController.class, "ENGINE_CONFIG", "engine_config_incomplete.json"); - String response = mockMvc.perform(MockMvcRequestBuilders.get("/transform/config")) - .andExpect(status().is(OK.value())).andExpect( - header().string(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)) + String response = mockMvc + .perform(MockMvcRequestBuilders.get("/transform/config")) + .andExpect(status().is(OK.value())) + .andExpect(header().string(CONTENT_TYPE, APPLICATION_JSON_UTF8_VALUE)) .andReturn().getResponse().getContentAsString(); TransformConfig transformConfig = objectMapper.readValue(response, TransformConfig.class); @@ -384,9 +406,10 @@ public abstract class AbstractTransformerControllerTest ReflectionTestUtils.setField(AbstractTransformerController.class, "ENGINE_CONFIG", "engine_config_no_transform_options.json"); - String response = mockMvc.perform(MockMvcRequestBuilders.get("/transform/config")) - .andExpect(status().is(OK.value())).andExpect( - header().string(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)) + String response = mockMvc + .perform(MockMvcRequestBuilders.get("/transform/config")) + .andExpect(status().is(OK.value())) + .andExpect(header().string(CONTENT_TYPE, APPLICATION_JSON_UTF8_VALUE)) .andReturn().getResponse().getContentAsString(); TransformConfig transformConfig = objectMapper.readValue(response, TransformConfig.class); @@ -405,7 +428,8 @@ public abstract class AbstractTransformerControllerTest new TransformOptionValue(false, "page"), new TransformOptionValue(false, "width"), new TransformOptionGroup(false, transformOptionGroup)); - Map> transformOptionsMap = ImmutableMap.of("engineXOptions", transformOptions); + Map> transformOptionsMap = ImmutableMap.of("engineXOptions", + transformOptions); Transformer transformer = buildTransformer("application/pdf", "image/png", "engineXOptions", "engineX"); diff --git a/alfresco-transformer-base/src/test/java/org/alfresco/transformer/QueueTransformServiceTest.java b/alfresco-transformer-base/src/test/java/org/alfresco/transformer/QueueTransformServiceTest.java index 4275089b..ee9c02f4 100644 --- a/alfresco-transformer-base/src/test/java/org/alfresco/transformer/QueueTransformServiceTest.java +++ b/alfresco-transformer-base/src/test/java/org/alfresco/transformer/QueueTransformServiceTest.java @@ -27,11 +27,18 @@ package org.alfresco.transformer; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.CREATED; +import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; + +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.Message; import org.alfresco.transform.client.model.TransformReply; import org.alfresco.transform.client.model.TransformRequest; @@ -48,10 +55,6 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.jms.support.converter.MessageConversionException; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; - public class QueueTransformServiceTest { @Mock @@ -98,10 +101,13 @@ public class QueueTransformServiceTest ActiveMQQueue destination = new ActiveMQQueue(); msg.setJMSReplyTo(destination); - TransformReply reply = TransformReply.builder() - .withStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()).withErrorDetails( + TransformReply reply = TransformReply + .builder() + .withStatus(INTERNAL_SERVER_ERROR.value()) + .withErrorDetails( "JMS exception during T-Request deserialization of message with correlationID " - + msg.getCorrelationId() + ": null").build(); + + msg.getCorrelationId() + ": null") + .build(); doReturn(null).when(transformMessageConverter).fromMessage(msg); @@ -122,10 +128,13 @@ public class QueueTransformServiceTest ActiveMQQueue destination = new ActiveMQQueue(); msg.setJMSReplyTo(destination); - TransformReply reply = TransformReply.builder().withStatus(HttpStatus.BAD_REQUEST.value()) + TransformReply reply = TransformReply + .builder() + .withStatus(BAD_REQUEST.value()) .withErrorDetails( "Message conversion exception during T-Request deserialization of message with correlationID" - + msg.getCorrelationId() + ": null").build(); + + msg.getCorrelationId() + ": null") + .build(); doThrow(MessageConversionException.class).when(transformMessageConverter).fromMessage(msg); @@ -146,10 +155,13 @@ public class QueueTransformServiceTest ActiveMQQueue destination = new ActiveMQQueue(); msg.setJMSReplyTo(destination); - TransformReply reply = TransformReply.builder() - .withStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()).withErrorDetails( - "JMSException during T-Request deserialization of message with correlationID " + msg - .getCorrelationId() + ": null").build(); + TransformReply reply = TransformReply + .builder() + .withStatus(INTERNAL_SERVER_ERROR.value()) + .withErrorDetails( + "JMSException during T-Request deserialization of message with correlationID " + + msg.getCorrelationId() + ": null") + .build(); doThrow(JMSException.class).when(transformMessageConverter).fromMessage(msg); @@ -169,7 +181,9 @@ public class QueueTransformServiceTest msg.setJMSReplyTo(destination); TransformRequest request = new TransformRequest(); - TransformReply reply = TransformReply.builder().withStatus(HttpStatus.CREATED.value()) + TransformReply reply = TransformReply + .builder() + .withStatus(CREATED.value()) .build(); doReturn(request).when(transformMessageConverter).fromMessage(msg); @@ -208,7 +222,9 @@ public class QueueTransformServiceTest doReturn(destination).when(msg).getJMSReplyTo(); TransformRequest request = new TransformRequest(); - TransformReply reply = TransformReply.builder().withStatus(HttpStatus.CREATED.value()) + TransformReply reply = TransformReply + .builder() + .withStatus(CREATED.value()) .build(); doReturn(request).when(transformMessageConverter).fromMessage(msg); diff --git a/pom.xml b/pom.xml index 2e5ffa7a..eec8844c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 2.1.6.RELEASE + 2.1.7.RELEASE @@ -14,9 +14,11 @@ 2.1.0-EA5-SNAPSHOT pom - - 1.8 + 11 + 11 + 11 + latest 2.0.16 7.17 @@ -26,6 +28,7 @@ 1.0.2.3 5.15.9 2.9.9 + 2.9.9.2 3.2.9 @@ -46,7 +49,6 @@ - org.alfresco @@ -68,7 +70,6 @@ dom4j 2.1.1 - org.alfresco alfresco-data-model @@ -129,7 +130,7 @@ com.fasterxml.jackson.core jackson-databind - ${dependency.jackson.version} + ${dependency.jackson-databind.version} com.fasterxml.jackson.core @@ -307,7 +308,7 @@ io.fabric8 fabric8-maven-plugin - 4.1.0 + 4.2.0 io.fabric8