From e982486d334f2ed9cee69fabc2ba1735028db1a4 Mon Sep 17 00:00:00 2001 From: alandavis Date: Mon, 25 Jul 2022 11:44:51 +0100 Subject: [PATCH] Save point: [skip ci] * Split TransformStream and TransformProcess out of TransformHandler * TestFileInfo to FileInfo * Removed HttpRequestTests as it adds nothing now the controller is in the base * Initialised the internal context to TranformRequest tests --- .../AbstractTransformerControllerTest.java | 60 -- engines/aio/pom.xml | 6 + .../transform/aio/AIOPdfRendererIT.java | 4 +- .../alfresco/transform/aio/AIOQueueTest.java | 1 + .../org/alfresco/transform/aio/AIOTest.java | 9 +- .../transform/base/TransformController.java | 19 +- .../transform/base/TransformHandler.java | 239 ++------ .../transform/base/TransformManagerImpl.java | 143 ++--- .../transform/base/TransformProcess.java | 139 +++++ .../base/TransformStreamHandler.java | 108 ++++ .../base/messaging/TransformReplySender.java | 22 +- .../base/util/OutputStreamLengthRecorder.java | 6 +- .../transform/base/AbstractBaseTest.java | 403 ++++--------- .../transform/base/AbstractQueueTest.java | 19 +- .../base/{HttpTest.java => RestTest.java} | 2 +- .../base/TransformControllerAllInOneTest.java | 18 +- .../base/TransformControllerTest.java | 92 ++- .../transform/base/TransformHandlerTest.java | 85 +++ .../base/TransformStreamHandlerTest.java | 528 ++++++++++++++++++ .../imagemagick/ImageMagickQueueTest.java | 1 + .../imagemagick/ImageMagickTest.java | 6 - .../libreoffice/LibreOfficeQueueTest.java | 1 + .../libreoffice/LibreOfficeTest.java | 6 - .../RFC822MetadataExtractor.java | 2 + .../transform/misc/MiscQueueTest.java | 4 +- .../org/alfresco/transform/misc/MiscTest.java | 7 - .../pdfrenderer/PdfRendererQueueTest.java | 4 +- .../pdfrenderer/PdfRendererTest.java | 6 - ....java => PdfRendererTransformationIT.java} | 5 +- .../transform/tika/TikaQueueTest.java | 4 +- .../org/alfresco/transform/tika/TikaTest.java | 76 +-- .../client/model/TransformRequest.java | 34 ++ .../messages/TransformStackTest.java | 2 +- .../registry/CombinedTransformConfigTest.java | 74 ++- ...gistry.java => FakeTransformRegistry.java} | 2 +- .../OverrideTransformConfigTests.java | 2 +- .../resources/engine_config_complete.json | 0 .../resources/engine_config_incomplete.json | 0 .../engine_config_no_transform_options.json | 0 .../engine_config_with_duplicates.json | 0 40 files changed, 1330 insertions(+), 809 deletions(-) create mode 100644 engines/base/src/main/java/org/alfresco/transform/base/TransformProcess.java create mode 100644 engines/base/src/main/java/org/alfresco/transform/base/TransformStreamHandler.java rename engines/base/src/test/java/org/alfresco/transform/base/{HttpTest.java => RestTest.java} (99%) create mode 100644 engines/base/src/test/java/org/alfresco/transform/base/TransformStreamHandlerTest.java rename engines/pdfrenderer/src/test/java/org/alfresco/transform/pdfrenderer/{AlfrescoPdfRendererTransformationIT.java => PdfRendererTransformationIT.java} (96%) rename model/src/test/java/org/alfresco/transform/registry/{TestTransformRegistry.java => FakeTransformRegistry.java} (97%) rename {engines/base => model}/src/test/resources/engine_config_complete.json (100%) rename {engines/base => model}/src/test/resources/engine_config_incomplete.json (100%) rename {engines/base => model}/src/test/resources/engine_config_no_transform_options.json (100%) rename {engines/base => model}/src/test/resources/engine_config_with_duplicates.json (100%) diff --git a/deprecated/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractTransformerControllerTest.java b/deprecated/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractTransformerControllerTest.java index bbf1de72..534f3033 100644 --- a/deprecated/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractTransformerControllerTest.java +++ b/deprecated/alfresco-transformer-base/src/test/java/org/alfresco/transformer/AbstractTransformerControllerTest.java @@ -610,64 +610,4 @@ public abstract class AbstractTransformerControllerTest transformer.setSupportedSourceAndTargetList(supportedSourceAndTargetList); return transformer; } - - @Test - public void queueTransformRequestUsingDirectAccessUrlTest() throws Exception - { - // Files - String sourceFileRef = UUID.randomUUID().toString(); - File sourceFile = getTestFile("quick." + sourceExtension, true); - String targetFileRef = UUID.randomUUID().toString(); - - TransformRequest transformRequest = createTransformRequest(sourceFileRef, sourceFile); - Map transformRequestOptions = transformRequest.getTransformRequestOptions(); - - String directUrl = "file://" + sourceFile.toPath(); - - transformRequestOptions.put(DIRECT_ACCESS_URL, directUrl); - transformRequest.setTransformRequestOptions(transformRequestOptions); - - when(alfrescoSharedFileStoreClient.saveFile(any())) - .thenReturn(new FileRefResponse(new FileRefEntity(targetFileRef))); - - // Update the Transformation Request with any specific params before sending it - updateTransformRequestWithSpecificOptions(transformRequest); - - // Serialize and call the transformer - String tr = objectMapper.writeValueAsString(transformRequest); - 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); - - // Assert the reply - assertEquals(transformRequest.getRequestId(), transformReply.getRequestId()); - assertEquals(transformRequest.getClientData(), transformReply.getClientData()); - assertEquals(transformRequest.getSchema(), transformReply.getSchema()); - } - - @Test - public void httpTransformRequestUsingDirectAccessUrlTest() throws Exception - { - File dauSourceFile = getTestFile("quick." + sourceExtension, true); - String directUrl = "file://" + dauSourceFile.toPath(); - - ResultActions resultActions = mockMvc.perform( - mockMvcRequest(ENDPOINT_TRANSFORM, null) - .param("targetExtension", targetExtension) - .param(DIRECT_ACCESS_URL, directUrl)) - .andExpect(status().is(OK.value())); - - if (expectedTargetFileBytes != null) - { - resultActions.andExpect(content().bytes(expectedTargetFileBytes)); - } - } } diff --git a/engines/aio/pom.xml b/engines/aio/pom.xml index 7a284e0b..6e9e93ae 100644 --- a/engines/aio/pom.xml +++ b/engines/aio/pom.xml @@ -53,6 +53,12 @@ org.alfresco alfresco-jodconverter-core + + + commons-io + commons-io + + org.apache.pdfbox diff --git a/engines/aio/src/test/java/org/alfresco/transform/aio/AIOPdfRendererIT.java b/engines/aio/src/test/java/org/alfresco/transform/aio/AIOPdfRendererIT.java index 2f53dd8c..f3685e87 100644 --- a/engines/aio/src/test/java/org/alfresco/transform/aio/AIOPdfRendererIT.java +++ b/engines/aio/src/test/java/org/alfresco/transform/aio/AIOPdfRendererIT.java @@ -26,8 +26,8 @@ */ package org.alfresco.transform.aio; -import org.alfresco.transform.pdfrenderer.AlfrescoPdfRendererTransformationIT; +import org.alfresco.transform.pdfrenderer.PdfRendererTransformationIT; -public class AIOPdfRendererIT extends AlfrescoPdfRendererTransformationIT +public class AIOPdfRendererIT extends PdfRendererTransformationIT { } diff --git a/engines/aio/src/test/java/org/alfresco/transform/aio/AIOQueueTest.java b/engines/aio/src/test/java/org/alfresco/transform/aio/AIOQueueTest.java index 8e03922d..73640a88 100644 --- a/engines/aio/src/test/java/org/alfresco/transform/aio/AIOQueueTest.java +++ b/engines/aio/src/test/java/org/alfresco/transform/aio/AIOQueueTest.java @@ -53,6 +53,7 @@ public class AIOQueueTest extends AbstractQueueTest .withClientData("ACS") .withSourceReference(UUID.randomUUID().toString()) .withSourceSize(32L) + .withInternalContextForTransformEngineTests() .build(); } } \ No newline at end of file diff --git a/engines/aio/src/test/java/org/alfresco/transform/aio/AIOTest.java b/engines/aio/src/test/java/org/alfresco/transform/aio/AIOTest.java index d1e55f5b..9433436f 100644 --- a/engines/aio/src/test/java/org/alfresco/transform/aio/AIOTest.java +++ b/engines/aio/src/test/java/org/alfresco/transform/aio/AIOTest.java @@ -30,6 +30,7 @@ import org.alfresco.transform.base.AbstractBaseTest; import org.alfresco.transform.client.model.TransformRequest; import org.alfresco.transform.config.TransformConfig; import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.http.ResponseEntity; @@ -51,13 +52,13 @@ public class AIOTest extends AbstractBaseTest //@Override protected void mockTransformCommand(String sourceExtension, String targetExtension, String sourceMimetype, - boolean readTargetFileBytes) throws IOException { - // TODO Auto-generated method stub + boolean readTargetFileBytes) throws IOException + { } //@Override - protected void updateTransformRequestWithSpecificOptions(TransformRequest transformRequest) { - // TODO Auto-generated method stub + protected void updateTransformRequestWithSpecificOptions(TransformRequest transformRequest) + { } @Test diff --git a/engines/base/src/main/java/org/alfresco/transform/base/TransformController.java b/engines/base/src/main/java/org/alfresco/transform/base/TransformController.java index 399e42b6..988efa15 100644 --- a/engines/base/src/main/java/org/alfresco/transform/base/TransformController.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/TransformController.java @@ -28,6 +28,8 @@ package org.alfresco.transform.base; import org.alfresco.transform.base.logging.LogEntry; import org.alfresco.transform.base.probes.ProbeTransform; +import org.alfresco.transform.client.model.TransformReply; +import org.alfresco.transform.client.model.TransformRequest; import org.alfresco.transform.common.TransformException; import org.alfresco.transform.config.TransformConfig; import org.alfresco.transform.registry.TransformServiceRegistry; @@ -44,6 +46,7 @@ import org.springframework.web.bind.MissingServletRequestParameterException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; @@ -80,6 +83,7 @@ import static org.alfresco.transform.common.RequestParamMap.TARGET_MIMETYPE; import static org.alfresco.transform.config.CoreVersionDecorator.setOrClearCoreVersion; import static org.springframework.http.HttpStatus.BAD_REQUEST; import static org.springframework.http.HttpStatus.OK; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE; /** @@ -106,7 +110,7 @@ public class TransformController private void init() { transformEngine = transformHandler.getTransformEngine(); - probeTransform = transformHandler.getProbeTestTransform(); + probeTransform = transformHandler.getProbeTransform(); } @EventListener(ApplicationReadyEvent.class) @@ -205,6 +209,18 @@ public class TransformController return new ResponseEntity<>(transformConfig, OK); } + // Only used for testing, but could be used in place of the /transform endpoint used by Alfresco Repository's + // 'Local Transforms'. In production, TransformRequests are processed is via a message queue. + @PostMapping(value = ENDPOINT_TRANSFORM, produces = APPLICATION_JSON_VALUE) + @ResponseBody + public ResponseEntity transform(@RequestBody TransformRequest request, + @RequestParam(value = "timeout", required = false) Long timeout) + { + TransformReply reply = transformHandler.handleMessageRequest(request, timeout, null); + return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus())); + } + + // Used by Alfresco Repository's 'Local Transforms'. Uploads the content and downloads the result. @PostMapping(value = ENDPOINT_TRANSFORM, consumes = MULTIPART_FORM_DATA_VALUE) public ResponseEntity transform(HttpServletRequest request, @RequestParam(value = FILE, required = false) MultipartFile sourceMultipartFile, @@ -216,6 +232,7 @@ public class TransformController targetMimetype, requestParameters); } + // Used the t-engine's simple html test UI. @PostMapping(value = ENDPOINT_TEST, consumes = MULTIPART_FORM_DATA_VALUE) public ResponseEntity testTransform(HttpServletRequest request, @RequestParam(value = FILE, required = false) MultipartFile sourceMultipartFile, diff --git a/engines/base/src/main/java/org/alfresco/transform/base/TransformHandler.java b/engines/base/src/main/java/org/alfresco/transform/base/TransformHandler.java index b50520dd..104f2c4b 100644 --- a/engines/base/src/main/java/org/alfresco/transform/base/TransformHandler.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/TransformHandler.java @@ -27,7 +27,6 @@ package org.alfresco.transform.base; import org.alfresco.transform.base.clients.AlfrescoSharedFileStoreClient; -import org.alfresco.transform.base.logging.LogEntry; import org.alfresco.transform.base.messaging.TransformReplySender; import org.alfresco.transform.base.model.FileRefResponse; import org.alfresco.transform.base.probes.ProbeTransform; @@ -84,11 +83,11 @@ import static org.alfresco.transform.common.RequestParamMap.DIRECT_ACCESS_URL; import static org.alfresco.transform.common.RequestParamMap.SOURCE_ENCODING; import static org.alfresco.transform.common.RequestParamMap.SOURCE_EXTENSION; import static org.alfresco.transform.common.RequestParamMap.SOURCE_MIMETYPE; +import static org.alfresco.transform.common.RequestParamMap.TARGET_EXTENSION; import static org.alfresco.transform.common.RequestParamMap.TARGET_MIMETYPE; 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; /** * Handles the transform requests from either http or a message. @@ -97,15 +96,14 @@ import static org.springframework.http.HttpStatus.OK; public class TransformHandler { private static final Logger logger = LoggerFactory.getLogger(TransformHandler.class); + private static final List NON_TRANSFORM_OPTION_REQUEST_PARAMETERS = Arrays.asList(SOURCE_EXTENSION, - TARGET_MIMETYPE, SOURCE_MIMETYPE, DIRECT_ACCESS_URL); + TARGET_EXTENSION, TARGET_MIMETYPE, SOURCE_MIMETYPE, DIRECT_ACCESS_URL); @Autowired(required = false) private List transformEngines; - @Autowired(required = false) private List customTransformers; - @Autowired private AlfrescoSharedFileStoreClient alfrescoSharedFileStoreClient; @Autowired @@ -177,121 +175,14 @@ public class TransformHandler return transformEngine; } - public ProbeTransform getProbeTestTransform() + public ProbeTransform getProbeTransform() { return probeTransform; } - private abstract class TransformProcess + public TransformerDebug getTransformerDebug() { - protected final String sourceMimetype; - protected final String targetMimetype; - private final Map transformOptions; - protected String reference; - - TransformProcess(String sourceMimetype, String targetMimetype, Map transformOptions, String reference) - { - this.sourceMimetype = sourceMimetype; - this.targetMimetype = targetMimetype; - this.transformOptions = cleanTransformOptions(transformOptions); - this.reference = reference; - } - void handleTransformRequest() - { - LogEntry.start(); - probeTransform.incrementTransformerCount(); - - TransformManagerImpl transformManager = TransformManagerImpl.builder() - .withSourceMimetype(sourceMimetype) - .withTargetMimetype(targetMimetype) - .build(); - InputStream inputStream = null; - try - { - init(transformManager); - - inputStream = getInputStream(transformManager); - long sourceSizeInBytes = getSourceSize(); - String transformName = getTransformerName(sourceSizeInBytes, sourceMimetype, targetMimetype, transformOptions); - CustomTransformer customTransformer = getCustomTransformer(transformName); - - transformerDebugPushTransform(sourceSizeInBytes, transformOptions, transformName); - - OutputStream outputStream = getOutputStream(transformManager); - try - { - customTransformer.transform(sourceMimetype, inputStream, - targetMimetype, outputStream, transformOptions, transformManager); - transformManager.ifUsedCopyTargetFileToOutputStream(); - - sendTransformResponse(transformManager); - - LogEntry.setTargetSize(transformManager.getOutputLength()); - LogEntry.setStatusCodeAndMessage(OK, "Success"); - } - finally - { - closeOutputStream(transformManager); - } - } - catch (TransformException e) - { - transformerDebug.logFailure(reference, e.getMessage()); - LogEntry.setStatusCodeAndMessage(e.getStatus(), e.getMessage()); - handleTransformException(e, e.getStatus()); - } - catch (Exception e) - { - transformerDebug.logFailure(reference, e.getMessage()); - LogEntry.setStatusCodeAndMessage(INTERNAL_SERVER_ERROR, e.getMessage()); - handleException(e, INTERNAL_SERVER_ERROR); - } - finally - { - closeInputStreamWithoutException(inputStream); - deleteTmpFiles(transformManager); - - long time = LogEntry.getTransformDuration(); - probeTransform.recordTransformTime(time); - transformerDebug.popTransform(reference, time); - LogEntry.complete(); - } - } - - protected abstract void init(TransformManagerImpl transformManager); - - protected abstract InputStream getInputStream(TransformManagerImpl transformManager); - - protected abstract long getSourceSize(); - - protected void transformerDebugPushTransform(long sourceSizeInBytes, Map transformOptions, String transformName) - { - transformerDebug.pushTransform(reference, sourceMimetype, targetMimetype, sourceSizeInBytes, transformName); - transformerDebug.logOptions(reference, transformOptions); - } - - protected abstract OutputStream getOutputStream(TransformManagerImpl transformManager) - throws FileNotFoundException; - - protected void sendTransformResponse(TransformManagerImpl transformManager) - { - // Only used in handleMessageRequest(...) - } - - protected void closeOutputStream(TransformManagerImpl transformManager) throws IOException - { - transformManager.getOutputStream().close(); - } - - protected void handleTransformException(TransformException e, HttpStatus status) - { - throw e; - } - - protected void handleException(Exception e, HttpStatus status) - { - throw new RuntimeException(e); - } + return transformerDebug; } public ResponseEntity handleHttpRequest(HttpServletRequest request, @@ -300,19 +191,20 @@ public class TransformHandler { return createResponseEntity(targetMimetype, os -> { - new TransformProcess(sourceMimetype, targetMimetype, requestParameters, + new TransformProcess(this, sourceMimetype, targetMimetype, requestParameters, "e" + httpRequestCount.getAndIncrement()) { @Override - protected void init(TransformManagerImpl transformManager) + protected void init() throws IOException { transformManager.setRequest(request); + super.init(); } @Override - protected InputStream getInputStream(TransformManagerImpl transformManager) + protected InputStream getInputStream() { - return getInputStreamForHandleHttpRequest(requestParameters, sourceMultipartFile, transformManager); + return getInputStreamForHandleHttpRequest(requestParameters, sourceMultipartFile); } @Override @@ -322,13 +214,13 @@ public class TransformHandler } @Override - protected OutputStream getOutputStream(TransformManagerImpl transformManager) + protected OutputStream getOutputStream() { return transformManager.setOutputStream(os); } @Override - protected void closeOutputStream(TransformManagerImpl transformManager) throws IOException + protected void closeOutputStream() throws IOException { // Do nothing as the Spring mvc handles this for HttpServletRequest } @@ -339,22 +231,22 @@ public class TransformHandler public void handleProbRequest(String sourceMimetype, String targetMimetype, Map transformOptions, File sourceFile, File targetFile) { - new TransformProcess(sourceMimetype, targetMimetype, transformOptions, + new TransformProcess(this, sourceMimetype, targetMimetype, transformOptions, "p" + httpRequestCount.getAndIncrement()) { @Override - protected void init(TransformManagerImpl transformManager) + protected void init() throws IOException { transformManager.setSourceFile(sourceFile); transformManager.setTargetFile(targetFile); - transformManager.setSourceFileCreated(); - // We don't want to delete the target file, so don't call setTargetFileCreated() + transformManager.keepTargetFile(); + super.init(); } @Override - protected InputStream getInputStream(TransformManagerImpl transformManager) + protected InputStream getInputStream() { - return getInputStreamForHandleProbRequest(sourceFile, transformManager); + return getInputStreamForHandleProbRequest(sourceFile); } @Override @@ -364,39 +256,31 @@ public class TransformHandler } @Override - protected OutputStream getOutputStream(TransformManagerImpl transformManager) - throws FileNotFoundException + protected OutputStream getOutputStream() throws IOException { - return getOutputStreamFromFile(targetFile, transformManager); + return getOutputStreamFromFile(targetFile); } }.handleTransformRequest(); } - public void handleMessageRequest(TransformRequest request, Long timeout, Destination replyToQueue) + public TransformReply handleMessageRequest(TransformRequest request, Long timeout, Destination replyToQueue) { - new TransformProcess(request.getSourceMediaType(), request.getTargetMediaType(), + TransformReply reply = createBasicTransformReply(request); + new TransformProcess(this, request.getSourceMediaType(), request.getTargetMediaType(), request.getTransformRequestOptions(), "unset") { - TransformReply reply = createBasicTransformReply(request); - @Override - protected void init(TransformManagerImpl transformManager) + protected void init() throws IOException { checkTransformRequestValid(request, reply); reference = TransformStack.getReference(reply.getInternalContext()); + super.init(); } @Override - protected InputStream getInputStream(TransformManagerImpl transformManager) + protected InputStream getInputStream() { - return getInputStreamForHandleMessageRequest(request, transformManager); - } - - @Override - protected void transformerDebugPushTransform(long sourceSizeInBytes, Map transformOptions, String transformName) - { - transformerDebug.pushTransform(request); - transformerDebug.logOptions(request); + return getInputStreamForHandleMessageRequest(request); } @Override @@ -406,12 +290,10 @@ public class TransformHandler } @Override - protected OutputStream getOutputStream(TransformManagerImpl transformManager) - throws FileNotFoundException + protected OutputStream getOutputStream() throws IOException { File targetFile = transformManager.setTargetFile(createTargetFile(null, sourceMimetype, targetMimetype)); - transformManager.setTargetFileCreated(); - return getOutputStreamFromFile(targetFile, transformManager); + return getOutputStreamFromFile(targetFile); } protected void sendTransformResponse(TransformManagerImpl transformManager) @@ -428,11 +310,12 @@ public class TransformHandler } @Override - protected void handleException(Exception e, HttpStatus status) + protected void handleException(Exception e) { - sendFailedResponse(reply, e, status, replyToQueue); + sendFailedResponse(reply, e, INTERNAL_SERVER_ERROR, replyToQueue); } }.handleTransformRequest(); + return reply; } private void sendSuccessfulResponse(Long timeout, TransformReply reply, Destination replyToQueue) @@ -451,15 +334,6 @@ public class TransformHandler transformReplySender.send(replyToQueue, reply); } - private void deleteTmpFiles(TransformManagerImpl transformManager) - { - if (transformManager != null) - { - transformManager.deleteSourceFileIfCreated(); - transformManager.deleteTargetFileIfCreated(); - } - } - private void checkTransformRequestValid(TransformRequest request, TransformReply reply) { final Errors errors = validateTransformRequest(request); @@ -507,7 +381,7 @@ public class TransformHandler request.setInternalContext(InternalContext.initialise(request.getInternalContext())); } - private Map cleanTransformOptions(Map requestParameters) + public Map cleanTransformOptions(Map requestParameters) { Map transformOptions = new HashMap<>(requestParameters); transformOptions.keySet().removeAll(NON_TRANSFORM_OPTION_REQUEST_PARAMETERS); @@ -539,19 +413,19 @@ public class TransformHandler } private InputStream getInputStreamForHandleHttpRequest(Map requestParameters, - MultipartFile sourceMultipartFile, TransformManagerImpl transformManager) + MultipartFile sourceMultipartFile) { final String directUrl = requestParameters.getOrDefault(DIRECT_ACCESS_URL, ""); - return transformManager.setInputStream(new BufferedInputStream(directUrl.isBlank() ? - getMultipartFileInputStream(sourceMultipartFile) : - getDirectAccessUrlInputStream(directUrl))); + return new BufferedInputStream(directUrl.isBlank() + ? getMultipartFileInputStream(sourceMultipartFile) + : getDirectAccessUrlInputStream(directUrl)); } - private InputStream getInputStreamForHandleProbRequest(File sourceFile, TransformManagerImpl transformManager) + private InputStream getInputStreamForHandleProbRequest(File sourceFile) { try { - return transformManager.setInputStream(new BufferedInputStream(new FileInputStream(sourceFile))); + return new BufferedInputStream(new FileInputStream(sourceFile)); } catch (FileNotFoundException e) { @@ -559,15 +433,14 @@ public class TransformHandler } } - private InputStream getInputStreamForHandleMessageRequest(TransformRequest request, - TransformManagerImpl transformManager) + private InputStream getInputStreamForHandleMessageRequest(TransformRequest request) { final String directUrl = request.getTransformRequestOptions().getOrDefault(DIRECT_ACCESS_URL, ""); try { - return transformManager.setInputStream(new BufferedInputStream(directUrl.isBlank() + return new BufferedInputStream(directUrl.isBlank() ? getSharedFileStoreInputStream(request.getSourceReference()) - : getDirectAccessUrlInputStream(directUrl))); + : getDirectAccessUrlInputStream(directUrl)); } catch (TransformException e) { @@ -579,10 +452,9 @@ public class TransformHandler } } - private OutputStream getOutputStreamFromFile(File targetFile, TransformManagerImpl transformManager) - throws FileNotFoundException + private OutputStream getOutputStreamFromFile(File targetFile) throws IOException { - return transformManager.setOutputStream(new BufferedOutputStream(new FileOutputStream(targetFile))); + return new BufferedOutputStream(new FileOutputStream(targetFile)); } private void saveTargetFileInSharedFileStore(File targetFile, TransformReply reply) @@ -627,8 +499,8 @@ public class TransformHandler return sb.toString(); } - private String getTransformerName(long sourceSizeInBytes, final String sourceMimetype, - final String targetMimetype, final Map transformOptions) + public String getTransformerName(final String sourceMimetype, long sourceSizeInBytes, final String targetMimetype, + final Map transformOptions) { // The transformOptions always contains sourceEncoding when sent to a T-Engine, even though it should not be // used to select a transformer. Similar to source and target mimetypes and extensions, but these are not @@ -656,7 +528,7 @@ public class TransformHandler } } - private CustomTransformer getCustomTransformer(String transformName) + public CustomTransformer getCustomTransformer(String transformName) { CustomTransformer customTransformer = customTransformersByName.get(transformName); if (customTransformer == null) @@ -666,21 +538,6 @@ public class TransformHandler return customTransformer; } - private void closeInputStreamWithoutException(InputStream inputStream) - { - if (inputStream != null) - { - try - { - inputStream.close(); - } - catch (IOException e) - { - throw new RuntimeException(e); - } - } - } - private ResponseEntity createResponseEntity(String targetMimetype, StreamingResponseBody body) { diff --git a/engines/base/src/main/java/org/alfresco/transform/base/TransformManagerImpl.java b/engines/base/src/main/java/org/alfresco/transform/base/TransformManagerImpl.java index c4a0a463..4e64f3ac 100644 --- a/engines/base/src/main/java/org/alfresco/transform/base/TransformManagerImpl.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/TransformManagerImpl.java @@ -34,11 +34,12 @@ import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import java.io.File; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** - * Manages the input and output streams and any temporary files that have been created, which will need to be deleted. + * Manages the input and output streams and any temporary files that have been created. */ @Component public class TransformManagerImpl implements TransformManager @@ -52,27 +53,11 @@ public class TransformManagerImpl implements TransformManager private String targetMimetype; private File sourceFile; private File targetFile; + private boolean keepTargetFile; private boolean createSourceFileCalled; private boolean createTargetFileCalled; - private boolean sourceFileCreated; - private boolean targetFileCreated; - - private TransformManagerImpl() - { - } - - public void init() - { - request = null; - inputStream = null; - outputStreamLengthRecorder = null; - sourceFile = null; - targetFile = null; - createSourceFileCalled = false; - createTargetFileCalled = false; - sourceFileCreated = false; - targetFileCreated = false; - } + private Boolean startedWithSourceFile; + private Boolean startedWithTargetFile; public void setRequest(HttpServletRequest request) { @@ -82,6 +67,10 @@ public class TransformManagerImpl implements TransformManager public InputStream setInputStream(InputStream inputStream) { this.inputStream = inputStream; + if (startedWithSourceFile == null) + { + startedWithSourceFile = false; + } return inputStream; } @@ -92,8 +81,12 @@ public class TransformManagerImpl implements TransformManager public OutputStream setOutputStream(OutputStream outputStream) { - this.outputStreamLengthRecorder = new OutputStreamLengthRecorder(outputStream); - return outputStream; + outputStreamLengthRecorder = new OutputStreamLengthRecorder(outputStream); + if (startedWithTargetFile == null) + { + startedWithTargetFile = false; + } + return outputStreamLengthRecorder; } public Long getOutputLength() @@ -119,27 +112,30 @@ public class TransformManagerImpl implements TransformManager public void setSourceFile(File sourceFile) { this.sourceFile = sourceFile; + if (startedWithSourceFile == null) + { + startedWithSourceFile = true; + } } - public File getTargetFile() { + public File getTargetFile() + { return targetFile; } File setTargetFile(File targetFile) { this.targetFile = targetFile; + if (startedWithTargetFile == null) + { + startedWithTargetFile = true; + } return targetFile; } - - public void setTargetFileCreated() + public void keepTargetFile() { - targetFileCreated = true; - } - - public void setSourceFileCreated() - { - sourceFileCreated = true; + keepTargetFile = true; } @Override public File createSourceFile() @@ -153,7 +149,6 @@ public class TransformManagerImpl implements TransformManager if (sourceFile == null) { sourceFile = FileManager.createSourceFile(request, inputStream, sourceMimetype); - sourceFileCreated = true; } return sourceFile; } @@ -169,36 +164,45 @@ public class TransformManagerImpl implements TransformManager if (targetFile == null) { targetFile = FileManager.createTargetFile(request, sourceMimetype, targetMimetype); - targetFileCreated = true; } return targetFile; } - public void ifUsedCopyTargetFileToOutputStream() + public void copyTargetFileToOutputStream() throws IOException { - if (targetFileCreated) + if (targetFile != null) { - FileManager.copyFileToOutputStream(targetFile, outputStreamLengthRecorder); + if (startedWithTargetFile == false) + { + FileManager.copyFileToOutputStream(targetFile, outputStreamLengthRecorder); + } + else if (createTargetFileCalled) + { + outputStreamLengthRecorder.setByteCount(targetFile.length()); + } + else + { + outputStreamLengthRecorder.flush(); + } } } - public void deleteSourceFileIfCreated() + public void deleteSourceFile() { - if (sourceFile != null && sourceFileCreated && !sourceFile.delete()) + if (sourceFile != null && !sourceFile.delete()) { logger.error("Failed to delete temporary source file "+sourceFile.getPath()); } sourceFile = null; } - public void deleteTargetFileIfCreated() + public void deleteTargetFile() { - if (targetFile != null && targetFileCreated && !targetFile.delete()) + if (!keepTargetFile && targetFile != null && !targetFile.delete()) { logger.error("Failed to delete temporary target file "+targetFile.getPath()); } targetFile = null; - targetFileCreated = false; } @Override @@ -213,61 +217,4 @@ public class TransformManagerImpl implements TransformManager // TODO send the current output as a TransformResponse and then start a new one. throw new UnsupportedOperationException("Not currently supported"); } - - public static Builder builder() - { - return new Builder(); - } - - public static class Builder - { - private final TransformManagerImpl transformManager = new TransformManagerImpl(); - - public TransformManagerImpl build() - { - return transformManager; - } - - public Builder withSourceMimetype(String sourceMimetype) - { - transformManager.sourceMimetype = sourceMimetype; - return this; - } - - public Builder withTargetMimetype(String targetMimetype) - { - transformManager.targetMimetype = targetMimetype; - return this; - } - - public Builder withInputStream(InputStream inputStream) - { - transformManager.inputStream = inputStream; - return this; - } - - public Builder withOutputStream(OutputStreamLengthRecorder outputStream) - { - transformManager.setOutputStream(outputStream); - return this; - } - - public Builder withRequest(HttpServletRequest request) - { - transformManager.request = request; - return this; - } - - public Builder withSourceFile(File sourceFile) - { - transformManager.sourceFile = sourceFile; - return this; - } - - public Builder withTargetFile(File targetFile) - { - transformManager.targetFile = targetFile; - return this; - } - } } diff --git a/engines/base/src/main/java/org/alfresco/transform/base/TransformProcess.java b/engines/base/src/main/java/org/alfresco/transform/base/TransformProcess.java new file mode 100644 index 00000000..57736d39 --- /dev/null +++ b/engines/base/src/main/java/org/alfresco/transform/base/TransformProcess.java @@ -0,0 +1,139 @@ +/* + * #%L + * Alfresco Transform Core + * %% + * Copyright (C) 2022 - 2022 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.transform.base; + +import org.alfresco.transform.base.logging.LogEntry; +import org.alfresco.transform.client.model.TransformRequest; +import org.alfresco.transform.common.TransformException; +import org.alfresco.transform.common.TransformerDebug; +import org.springframework.http.HttpStatus; +import org.springframework.web.multipart.MultipartFile; + +import javax.jms.Destination; +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.util.Map; + +import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; +import static org.springframework.http.HttpStatus.OK; + +/** + * Provides the transform logic common to http upload/download, message and probe requests. See + * {@link TransformHandler#handleHttpRequest(HttpServletRequest, MultipartFile, String, String, Map)}, + * {@link TransformHandler#handleMessageRequest(TransformRequest, Long, Destination)} and + * {@link TransformHandler#handleProbRequest(String, String, Map, File, File)}. Note the handing of transform requests + * via a message queue is the same as via the {@link TransformController#transform(TransformRequest, Long)}. + */ +abstract class TransformProcess extends TransformStreamHandler +{ + private final TransformHandler transformHandler; + private final TransformerDebug transformerDebug; + protected final String sourceMimetype; + protected final String targetMimetype; + private final Map transformOptions; + protected String reference; + + TransformProcess(TransformHandler transformHandler, String sourceMimetype, String targetMimetype, + Map transformOptions, String reference) + { + LogEntry.start(); + this.transformHandler = transformHandler; + this.sourceMimetype = sourceMimetype; + this.targetMimetype = targetMimetype; + this.transformOptions = transformHandler.cleanTransformOptions(transformOptions); + this.reference = reference; + this.transformerDebug = transformHandler.getTransformerDebug(); + transformHandler.getProbeTransform().incrementTransformerCount(); + } + + @Override + public void handleTransformRequest() + { + transformManager.setSourceMimetype(sourceMimetype); + transformManager.setTargetMimetype(targetMimetype); + try + { + init(); + long sourceSizeInBytes = getSourceSize(); + String transformName = transformHandler.getTransformerName(sourceMimetype, sourceSizeInBytes, targetMimetype, transformOptions); + CustomTransformer customTransformer = transformHandler.getCustomTransformer(transformName); + transformerDebug.pushTransform(reference, sourceMimetype, targetMimetype, sourceSizeInBytes, transformName); + transformerDebug.logOptions(reference, transformOptions); + handleTransform(customTransformer); + } + catch (TransformException e) + { + transformerDebug.logFailure(reference, e.getMessage()); + LogEntry.setStatusCodeAndMessage(e.getStatus(), e.getMessage()); + handleTransformException(e, e.getStatus()); + } + catch (Exception e) + { + transformerDebug.logFailure(reference, e.getMessage()); + LogEntry.setStatusCodeAndMessage(INTERNAL_SERVER_ERROR, e.getMessage()); + handleException(e); + } + finally + { + long time = LogEntry.getTransformDuration(); + transformHandler.getProbeTransform().recordTransformTime(time); + transformerDebug.popTransform(reference, time); + LogEntry.complete(); + } + } + + @Override + public void transform(CustomTransformer customTransformer) throws Exception + { + customTransformer.transform(sourceMimetype, inputStream, targetMimetype, outputStream, transformOptions, transformManager); + } + + protected abstract long getSourceSize(); + + @Override + public void onSuccessfulTransform() + { + sendTransformResponse(transformManager); + + LogEntry.setTargetSize(transformManager.getOutputLength()); + LogEntry.setStatusCodeAndMessage(OK, "Success"); + } + protected void sendTransformResponse(TransformManagerImpl transformManager) + { + // Only used in handleMessageRequest(...) + } + + protected void handleTransformException(TransformException e, HttpStatus status) + { + throw e; + } + + protected void handleException(Exception e) + { + throw new RuntimeException(e); + } +} diff --git a/engines/base/src/main/java/org/alfresco/transform/base/TransformStreamHandler.java b/engines/base/src/main/java/org/alfresco/transform/base/TransformStreamHandler.java new file mode 100644 index 00000000..c8c0ce4a --- /dev/null +++ b/engines/base/src/main/java/org/alfresco/transform/base/TransformStreamHandler.java @@ -0,0 +1,108 @@ +/* + * #%L + * Alfresco Transform Core + * %% + * Copyright (C) 2022 - 2022 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.transform.base; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Separation of InputStream, OutputStream, sourceFile and targetFile from the {@link TransformProcess} logic. Allows + * {@link CustomTransformer} implementations to call {@link TransformManager#createSourceFile()} and + * {@link TransformManager#createTargetFile()} so that extra Files are not created if there was one already in + * existence. + * + * Subclasses MUST call transformManager.setSourceFile(File) and transformManager.setSourceFile(File) if they start + * with files rather than streams, before calling the {@link #init()} method which calls + * transformManager.setInputStream(InputStream) and transformManager.setOutputStream(OutputStream). + */ +public abstract class TransformStreamHandler +{ + protected TransformManagerImpl transformManager = new TransformManagerImpl(); + protected InputStream inputStream; + protected OutputStream outputStream; + + public abstract void handleTransformRequest() throws Exception; + + protected void init() throws IOException + { + inputStream = transformManager.setInputStream(getInputStream()); + outputStream = transformManager.setOutputStream(getOutputStream()); + } + + protected abstract InputStream getInputStream() throws IOException; + + protected abstract OutputStream getOutputStream() throws IOException; + + protected void handleTransform(CustomTransformer customTransformer) throws Exception + { + try + { + transform(customTransformer); + transformManager.copyTargetFileToOutputStream(); + onSuccessfulTransform(); + } + finally + { + closeOutputStream(); + closeInputStreamWithoutException(); + deleteTmpFiles(); + } + } + + protected abstract void transform(CustomTransformer customTransformer) throws Exception; + + protected void onSuccessfulTransform() + { + } + + protected void closeOutputStream() throws IOException + { + transformManager.getOutputStream().close(); + } + + private void closeInputStreamWithoutException() + { + if (inputStream != null) + { + try + { + inputStream.close(); + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } + } + + private void deleteTmpFiles() + { + transformManager.deleteSourceFile(); + transformManager.deleteTargetFile(); + } +} diff --git a/engines/base/src/main/java/org/alfresco/transform/base/messaging/TransformReplySender.java b/engines/base/src/main/java/org/alfresco/transform/base/messaging/TransformReplySender.java index b6dc5eb8..7b3f561d 100644 --- a/engines/base/src/main/java/org/alfresco/transform/base/messaging/TransformReplySender.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/messaging/TransformReplySender.java @@ -58,18 +58,18 @@ public class TransformReplySender public void send(final Destination destination, final TransformReply reply, final String correlationId) { - try + if (destination != null) { - //jmsTemplate.setSessionTransacted(true); // do we need this? - jmsTemplate.convertAndSend(destination, reply, m -> { - m.setJMSCorrelationID(correlationId); - return m; - }); - logger.trace("Sent: {} - with correlation ID {}", reply, correlationId); - } - catch (Exception e) - { - logger.error("Failed to send T-Reply " + reply + " - for correlation ID " + correlationId, e); + try { + //jmsTemplate.setSessionTransacted(true); // do we need this? + jmsTemplate.convertAndSend(destination, reply, m -> { + m.setJMSCorrelationID(correlationId); + return m; + }); + logger.trace("Sent: {} - with correlation ID {}", reply, correlationId); + } catch (Exception e) { + logger.error("Failed to send T-Reply " + reply + " - for correlation ID " + correlationId, e); + } } } } diff --git a/engines/base/src/main/java/org/alfresco/transform/base/util/OutputStreamLengthRecorder.java b/engines/base/src/main/java/org/alfresco/transform/base/util/OutputStreamLengthRecorder.java index ab644519..ae8742e6 100644 --- a/engines/base/src/main/java/org/alfresco/transform/base/util/OutputStreamLengthRecorder.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/util/OutputStreamLengthRecorder.java @@ -44,6 +44,11 @@ public class OutputStreamLengthRecorder extends FilterOutputStream return byteCount; } + public void setByteCount(long byteCount) + { + this.byteCount = byteCount; + } + public void write(int b) throws IOException { super.write(b); @@ -53,6 +58,5 @@ public class OutputStreamLengthRecorder extends FilterOutputStream public void write(byte b[], int off, int len) throws IOException { super.write(b, off, len); - byteCount += len; } } \ No newline at end of file diff --git a/engines/base/src/test/java/org/alfresco/transform/base/AbstractBaseTest.java b/engines/base/src/test/java/org/alfresco/transform/base/AbstractBaseTest.java index 7ffd082e..178ffd94 100644 --- a/engines/base/src/test/java/org/alfresco/transform/base/AbstractBaseTest.java +++ b/engines/base/src/test/java/org/alfresco/transform/base/AbstractBaseTest.java @@ -26,28 +26,29 @@ */ package org.alfresco.transform.base; -import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; -import static org.alfresco.transform.common.RequestParamMap.DIRECT_ACCESS_URL; -import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM; -import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM_CONFIG_LATEST; -import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM_CONFIG; -import static org.hamcrest.Matchers.containsString; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; -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.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.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.request; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.alfresco.transform.base.clients.AlfrescoSharedFileStoreClient; +import org.alfresco.transform.base.model.FileRefEntity; +import org.alfresco.transform.base.model.FileRefResponse; +import org.alfresco.transform.base.probes.ProbeTransform; +import org.alfresco.transform.client.model.InternalContext; +import org.alfresco.transform.client.model.TransformReply; +import org.alfresco.transform.client.model.TransformRequest; +import org.alfresco.transform.messages.TransformStack; +import org.alfresco.transform.registry.TransformServiceRegistry; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import java.io.File; import java.io.FileInputStream; @@ -57,47 +58,28 @@ import java.net.URL; import java.nio.channels.FileChannel; import java.nio.file.Files; import java.util.HashMap; -import java.util.List; import java.util.Map; -import java.util.Set; import java.util.UUID; -import org.alfresco.transform.base.probes.ProbeTransform; -import org.alfresco.transform.client.model.InternalContext; -import org.alfresco.transform.client.model.TransformReply; -import org.alfresco.transform.client.model.TransformRequest; -import org.alfresco.transform.config.SupportedSourceAndTarget; -import org.alfresco.transform.config.TransformConfig; -import org.alfresco.transform.config.TransformOption; -import org.alfresco.transform.config.TransformOptionGroup; -import org.alfresco.transform.config.TransformOptionValue; -import org.alfresco.transform.config.Transformer; -import org.alfresco.transform.registry.TransformServiceRegistry; -import org.alfresco.transform.messages.TransformStack; -import org.alfresco.transform.base.clients.AlfrescoSharedFileStoreClient; -import org.alfresco.transform.base.model.FileRefEntity; -import org.alfresco.transform.base.model.FileRefResponse; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; -import org.springframework.core.io.ClassPathResource; -import org.springframework.mock.web.MockMultipartFile; -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.MvcResult; -import org.springframework.test.web.servlet.ResultActions; -import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; +import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; +import static org.alfresco.transform.common.RequestParamMap.DIRECT_ACCESS_URL; +import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM; +import static org.hamcrest.Matchers.containsString; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +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.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.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch; +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.request; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** * Super class for testing. @@ -106,7 +88,9 @@ import com.google.common.collect.ImmutableSet; @AutoConfigureMockMvc public abstract class AbstractBaseTest { - @TempDir // added as part of ATS-702 to allow test resources to be read from the imported jar files to prevent test resource duplication + // Added as part of ATS-702 to allow test resources to be read from the imported jar files to prevent test + // resource duplication + @TempDir public File tempDir; @Autowired @@ -159,6 +143,32 @@ public abstract class AbstractBaseTest protected abstract void updateTransformRequestWithSpecificOptions(TransformRequest transformRequest); +// static void assertConfig(String url, String expectedTransformers, String expectedOptions, +// MockMvc mockMvc, ObjectMapper objectMapper) throws Exception +// { +// TransformConfig config = objectMapper.readValue( +// mockMvc.perform(MockMvcRequestBuilders.get(url)) +// .andExpect(status().isOk()) +// .andExpect(header().string(CONTENT_TYPE, APPLICATION_JSON_VALUE)) +// .andReturn() +// .getResponse() +// .getContentAsString(), TransformConfig.class); +// +// // Gets a list of transformerNames,coreVersion,optionNames +// assertEquals(expectedTransformers, +// config.getTransformers().stream() +// .map(t -> t.getTransformerName()+"," +// +t.getCoreVersion()+"," +// +t.getTransformOptions().stream().sorted().collect(Collectors.joining(","))) +// .sorted() +// .collect(Collectors.joining("\n"))); +// +// assertEquals(expectedOptions, +// config.getTransformOptions().keySet().stream() +// .sorted() +// .collect(Collectors.joining(","))); +// } +// /** * This method ends up being the core of the mock. * It copies content from an existing file in the resources folder to the desired location @@ -198,17 +208,23 @@ public abstract class AbstractBaseTest } protected File getTestFile(String testFilename, boolean required) throws IOException + { + return getTestFile(testFilename, required, tempDir); + } + + public static File getTestFile(String testFilename, boolean required, File tempDir) throws IOException { File testFile = null; - ClassLoader classLoader = getClass().getClassLoader(); + ClassLoader classLoader = AbstractBaseTest.class.getClassLoader(); URL testFileUrl = classLoader.getResource(testFilename); if (required && testFileUrl == null) { throw new IOException("The test file " + testFilename + " does not exist in the resources directory"); } - // added as part of ATS-702 to allow test resources to be read from the imported jar files to prevent test resource duplication - if (testFileUrl!=null) + // Added as part of ATS-702 to allow test resources to be read from the imported jar files to prevent test + // resource duplication + if (testFileUrl != null) { // Each use of the tempDir should result in a unique directory being used testFile = new File(tempDir, testFilename); @@ -265,26 +281,19 @@ public abstract class AbstractBaseTest protected TransformRequest createTransformRequest(String sourceFileRef, File sourceFile) { - TransformRequest transformRequest = new TransformRequest(); - transformRequest.setRequestId("1"); - transformRequest.setSchema(1); - transformRequest.setClientData("Alfresco Digital Business Platform"); - transformRequest.setTransformRequestOptions(options); - transformRequest.setSourceReference(sourceFileRef); - transformRequest.setSourceExtension(sourceExtension); - transformRequest.setSourceMediaType(sourceMimetype); - transformRequest.setSourceSize(sourceFile.length()); - transformRequest.setTargetExtension(targetExtension); - transformRequest.setTargetMediaType(targetMimetype); - transformRequest.setInternalContext(InternalContext.initialise(null)); - transformRequest.getInternalContext().getMultiStep().setInitialRequestId("123"); - transformRequest.getInternalContext().getMultiStep().setInitialSourceMediaType(sourceMimetype); - TransformStack.setInitialTransformRequestOptions(transformRequest.getInternalContext(), options); - TransformStack.setInitialSourceReference(transformRequest.getInternalContext(), sourceFileRef); - TransformStack.addTransformLevel(transformRequest.getInternalContext(), - TransformStack.levelBuilder(TransformStack.PIPELINE_FLAG) - .withStep("transformerName", sourceMimetype, targetMimetype)); - return transformRequest; + return TransformRequest.builder() + .withRequestId("1") + .withSchema(1) + .withClientData("Alfresco Digital Business Platform") + .withTransformRequestOptions(options) + .withSourceReference(sourceFileRef) + .withSourceExtension(sourceExtension) + .withSourceMediaType(sourceMimetype) + .withSourceSize(sourceFile.length()) + .withTargetExtension(targetExtension) + .withTargetMediaType(targetMimetype) + .withInternalContextForTransformEngineTests() + .build(); } @Test @@ -339,28 +348,6 @@ public abstract class AbstractBaseTest "attachment; filename*=UTF-8''transform." + targetExtension)); } - @Test - // Invalid file name that ends in / - public void badSourceFilenameTest() throws Exception - { - sourceFile = new MockMultipartFile("file", "abc/", sourceMimetype, sourceFileBytes); - - mockMvc.perform( - mockMvcRequest(ENDPOINT_TRANSFORM, sourceFile)) - .andExpect(status().is(BAD_REQUEST.value())) - .andExpect(status().reason(containsString("The source filename was not supplied"))); - } - - @Test - public void blankSourceFilenameTest() throws Exception - { - sourceFile = new MockMultipartFile("file", "", sourceMimetype, sourceFileBytes); - - mockMvc.perform( - mockMvcRequest(ENDPOINT_TRANSFORM, sourceFile)) - .andExpect(status().is(BAD_REQUEST.value())); - } - @Test public void calculateMaxTime() throws Exception { @@ -414,187 +401,6 @@ public abstract class AbstractBaseTest assertEquals(BAD_REQUEST.value(), transformReply.getStatus()); } - /** - * - * @return transformer specific engine config name - */ - public String getEngineConfigName() - { - return "engine_config.json"; - } - - @Test - public void testGetTransformConfigInfo() throws Exception - { - TransformConfig expectedTransformConfig = objectMapper - .readValue(getTestFile(getEngineConfigName(), true), - TransformConfig.class); - expectedTransformConfig.getTransformers().forEach(transformer -> { - transformer.setCoreVersion(coreVersion); - transformer.getTransformOptions().add(DIRECT_ACCESS_URL); - }); - expectedTransformConfig.getTransformOptions().put(DIRECT_ACCESS_URL, Set.of(new TransformOptionValue(false, DIRECT_ACCESS_URL))); - - ReflectionTestUtils.setField(transformRegistry, "engineConfig", - new ClassPathResource(getEngineConfigName())); - - String response = mockMvc - .perform(MockMvcRequestBuilders.get(ENDPOINT_TRANSFORM_CONFIG_LATEST)) - .andExpect(request().asyncStarted()) - .andDo(MvcResult::getAsyncResult) - .andExpect(status().isOk()) - .andExpect(header().string(CONTENT_TYPE, APPLICATION_JSON_VALUE)) - .andReturn().getResponse().getContentAsString(); - - TransformConfig transformConfig = objectMapper.readValue(response, TransformConfig.class); - assertEquals(expectedTransformConfig, transformConfig); - } - - @Test - // Test for case when T-Router or Repository is a version that does not expect it - public void testGetTransformConfigInfoExcludingCoreVersion() throws Exception - { - TransformConfig expectedTransformConfig = objectMapper - .readValue(getTestFile(getEngineConfigName(), true), - TransformConfig.class); - - ReflectionTestUtils.setField(transformRegistry, "engineConfig", - new ClassPathResource(getEngineConfigName())); - - String response = mockMvc - .perform(MockMvcRequestBuilders.get(ENDPOINT_TRANSFORM_CONFIG)) - .andExpect(request().asyncStarted()) - .andDo(MvcResult::getAsyncResult) - .andExpect(status().isOk()) - .andExpect(header().string(CONTENT_TYPE, APPLICATION_JSON_VALUE)) - .andReturn().getResponse().getContentAsString(); - - TransformConfig transformConfig = objectMapper.readValue(response, TransformConfig.class); - assertEquals(expectedTransformConfig, transformConfig); - } - - @Test - public void testGetInfoFromConfigWithDuplicates() throws Exception - { - TransformConfig expectedResult = buildCompleteTransformConfig(); - - ReflectionTestUtils.setField(transformRegistry, "engineConfig", - new ClassPathResource("engine_config_with_duplicates.json")); - - String response = mockMvc - .perform(MockMvcRequestBuilders.get(ENDPOINT_TRANSFORM_CONFIG)) - .andExpect(request().asyncStarted()) - .andDo(MvcResult::getAsyncResult) - .andExpect(status().isOk()) - .andExpect(header().string(CONTENT_TYPE, APPLICATION_JSON_VALUE)) - .andReturn().getResponse().getContentAsString(); - - TransformConfig transformConfig = objectMapper.readValue(response, TransformConfig.class); - - assertNotNull(transformConfig); - assertEquals(expectedResult, transformConfig); - assertEquals(3, transformConfig.getTransformOptions().get("engineXOptions").size()); - assertEquals(1, - transformConfig.getTransformers().get(0).getSupportedSourceAndTargetList().size()); - assertEquals(1, - transformConfig.getTransformers().get(0).getTransformOptions().size()); - } - - @Test - public void testGetInfoFromConfigWithEmptyTransformOptions() throws Exception - { - Transformer transformer = buildTransformer("application/pdf", "image/png"); - TransformConfig expectedResult = new TransformConfig(); - expectedResult.setTransformers(ImmutableList.of(transformer)); - - ReflectionTestUtils.setField(transformRegistry, "engineConfig", - new ClassPathResource("engine_config_incomplete.json")); - - String response = mockMvc - .perform(MockMvcRequestBuilders.get(ENDPOINT_TRANSFORM_CONFIG)) - .andExpect(request().asyncStarted()) - .andDo(MvcResult::getAsyncResult) - .andExpect(status().isOk()) - .andExpect(header().string(CONTENT_TYPE, APPLICATION_JSON_VALUE)) - .andReturn().getResponse().getContentAsString(); - - TransformConfig transformConfig = objectMapper.readValue(response, TransformConfig.class); - - assertNotNull(transformConfig); - assertEquals(expectedResult, transformConfig); - } - - @Test - public void testGetInfoFromConfigWithNoTransformOptions() throws Exception - { - Transformer transformer = buildTransformer("application/pdf", "image/png"); - transformer.setTransformerName("engineX"); - TransformConfig expectedResult = new TransformConfig(); - expectedResult.setTransformers(ImmutableList.of(transformer)); - - ReflectionTestUtils.setField(transformRegistry, "engineConfig", - new ClassPathResource("engine_config_no_transform_options.json")); - - String response = mockMvc - .perform(MockMvcRequestBuilders.get(ENDPOINT_TRANSFORM_CONFIG)) - .andExpect(request().asyncStarted()) - .andDo(MvcResult::getAsyncResult) - .andExpect(status().isOk()) - .andExpect(header().string(CONTENT_TYPE, APPLICATION_JSON_VALUE)) - .andReturn().getResponse().getContentAsString(); - - TransformConfig transformConfig = objectMapper.readValue(response, TransformConfig.class); - - assertNotNull(transformConfig); - assertEquals(expectedResult, transformConfig); - } - - private TransformConfig buildCompleteTransformConfig() - { - TransformConfig expectedResult = new TransformConfig(); - - Set transformOptionGroup = ImmutableSet.of( - new TransformOptionValue(false, "cropGravity")); - Set transformOptions = ImmutableSet.of( - new TransformOptionValue(false, "page"), - new TransformOptionValue(false, "width"), - new TransformOptionGroup(false, transformOptionGroup)); - Map> transformOptionsMap = ImmutableMap.of("engineXOptions", - transformOptions); - - Transformer transformer = buildTransformer("application/pdf", "image/png", "engineXOptions", - "engineX"); - List transformers = ImmutableList.of(transformer); - - expectedResult.setTransformOptions(transformOptionsMap); - expectedResult.setTransformers(transformers); - - return expectedResult; - } - - private Transformer buildTransformer(String sourceMediaType, String targetMediaType, - String transformOptions, String transformerName) - { - Transformer transformer = buildTransformer(sourceMediaType, targetMediaType); - transformer.setTransformerName(transformerName); - transformer.setTransformOptions(ImmutableSet.of(transformOptions)); - - return transformer; - } - - private Transformer buildTransformer(String sourceMediaType, String targetMediaType) - { - Set supportedSourceAndTargetList = ImmutableSet.of( - SupportedSourceAndTarget.builder() - .withSourceMediaType(sourceMediaType) - .withTargetMediaType(targetMediaType) - .build()); - - Transformer transformer = new Transformer(); - transformer.setSupportedSourceAndTargetList(supportedSourceAndTargetList); - return transformer; - } - @Test public void queueTransformRequestUsingDirectAccessUrlTest() throws Exception { @@ -609,7 +415,7 @@ public abstract class AbstractBaseTest String directUrl = "file://" + sourceFile.toPath(); transformRequestOptions.put(DIRECT_ACCESS_URL, directUrl); - transformRequest.setTransformRequestOptions(transformRequestOptions); +// transformRequest.setTransformRequestOptions(transformRequestOptions); when(alfrescoSharedFileStoreClient.saveFile(any())) .thenReturn(new FileRefResponse(new FileRefEntity(targetFileRef))); @@ -621,15 +427,13 @@ public abstract class AbstractBaseTest String tr = objectMapper.writeValueAsString(transformRequest); String transformationReplyAsString = mockMvc .perform(MockMvcRequestBuilders - .post("/transform") + .post(ENDPOINT_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()); @@ -643,11 +447,16 @@ public abstract class AbstractBaseTest File dauSourceFile = getTestFile("quick." + sourceExtension, true); String directUrl = "file://" + dauSourceFile.toPath(); - ResultActions resultActions = mockMvc.perform( - mockMvcRequest(ENDPOINT_TRANSFORM, null) - .param("targetExtension", targetExtension) - .param(DIRECT_ACCESS_URL, directUrl)) - .andExpect(status().is(OK.value())); + MvcResult mvcResult = mockMvc.perform( + mockMvcRequest(ENDPOINT_TRANSFORM, null) + .param(DIRECT_ACCESS_URL, directUrl)) + .andExpect(request().asyncStarted()) + .andReturn(); + + ResultActions resultActions = mockMvc.perform(asyncDispatch(mvcResult)) + .andExpect(status().isOk()) + .andExpect(header().string("Content-Disposition", + "attachment; filename*=UTF-8''transform."+targetExtension)); if (expectedTargetFileBytes != null) { diff --git a/engines/base/src/test/java/org/alfresco/transform/base/AbstractQueueTest.java b/engines/base/src/test/java/org/alfresco/transform/base/AbstractQueueTest.java index 90664786..952a6c50 100644 --- a/engines/base/src/test/java/org/alfresco/transform/base/AbstractQueueTest.java +++ b/engines/base/src/test/java/org/alfresco/transform/base/AbstractQueueTest.java @@ -46,7 +46,8 @@ import org.springframework.jms.core.JmsTemplate; /** * Checks that a t-engine can respond to its message queue. This is really just checking that - * ${queue.engineRequestQueue} has been configured. The transform request can (and does fail). + * ${queue.engineRequestQueue} has been configured. The transform request can (and does fail + * because the shared file store does not exist). * * @author Lucian Tuca * created on 15/01/2019 @@ -67,22 +68,6 @@ public abstract class AbstractQueueTest { TransformRequest request = buildRequest(); - // Router.initialiseContext(TransformRequest) - request.setInternalContext(InternalContext.initialise(request.getInternalContext())); - request.setTargetExtension(ExtensionService.getExtensionForTargetMimetype(request.getTargetMediaType(), - request.getSourceMediaType())); - request.getInternalContext().getMultiStep().setInitialRequestId(request.getRequestId()); - request.getInternalContext().getMultiStep().setInitialSourceMediaType(request.getSourceMediaType()); - request.getInternalContext().setTransformRequestOptions(request.getTransformRequestOptions()); - setInitialTransformRequestOptions(request.getInternalContext(), request.getTransformRequestOptions()); - TransformStack.setInitialSourceReference(request.getInternalContext(), request.getSourceReference()); - - TransformStack.addTransformLevel(request.getInternalContext(), levelBuilder(PIPELINE_FLAG) // pipeline of 1 - .withStep( - "transformerName", - request.getSourceMediaType(), - request.getTargetMediaType())); - jmsTemplate.convertAndSend(engineRequestQueue, request, m -> { m.setJMSCorrelationID(request.getRequestId()); m.setJMSReplyTo(testingQueue); diff --git a/engines/base/src/test/java/org/alfresco/transform/base/HttpTest.java b/engines/base/src/test/java/org/alfresco/transform/base/RestTest.java similarity index 99% rename from engines/base/src/test/java/org/alfresco/transform/base/HttpTest.java rename to engines/base/src/test/java/org/alfresco/transform/base/RestTest.java index 367f5245..82de31ca 100644 --- a/engines/base/src/test/java/org/alfresco/transform/base/HttpTest.java +++ b/engines/base/src/test/java/org/alfresco/transform/base/RestTest.java @@ -61,7 +61,7 @@ import static org.springframework.http.MediaType.MULTIPART_FORM_DATA; FakeTransformEngineWithTwoCustomTransformers.class, FakeTransformerTxT2Pdf.class, FakeTransformerPdf2Png.class}) -public class HttpTest +public class RestTest { @Autowired private TestRestTemplate restTemplate; diff --git a/engines/base/src/test/java/org/alfresco/transform/base/TransformControllerAllInOneTest.java b/engines/base/src/test/java/org/alfresco/transform/base/TransformControllerAllInOneTest.java index 828ed96e..d860b191 100644 --- a/engines/base/src/test/java/org/alfresco/transform/base/TransformControllerAllInOneTest.java +++ b/engines/base/src/test/java/org/alfresco/transform/base/TransformControllerAllInOneTest.java @@ -26,19 +26,19 @@ */ package org.alfresco.transform.base; +import com.fasterxml.jackson.databind.ObjectMapper; import org.alfresco.transform.base.fakes.FakeTransformEngineWithAllInOne; import org.alfresco.transform.base.fakes.FakeTransformEngineWithOneCustomTransformer; import org.alfresco.transform.base.fakes.FakeTransformEngineWithTwoCustomTransformers; import org.alfresco.transform.base.fakes.FakeTransformerPdf2Jpg; import org.alfresco.transform.base.fakes.FakeTransformerPdf2Png; import org.alfresco.transform.base.fakes.FakeTransformerTxT2Pdf; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.ContextConfiguration; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.mock.web.MockMultipartFile; +import org.springframework.test.context.ContextConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; @@ -66,10 +66,6 @@ import static org.alfresco.transform.common.RequestParamMap.TARGET_MIMETYPE; import static org.hamcrest.Matchers.containsString; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; @@ -77,10 +73,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** - * Testing base t-engine TransformController functionality where there are multiple TransformEngines brought together + * Testing TransformController functionality where there are multiple TransformEngines brought together * in a single t-engine. * - * Contains a subset of tests also in {@link TransformControllerTest}. + * Repeats a set of tests from {@link TransformControllerTest}, which tests the single TransformEngine case. */ @AutoConfigureMockMvc @SpringBootTest(classes={org.alfresco.transform.base.Application.class}) @@ -103,7 +99,7 @@ public class TransformControllerAllInOneTest private String coreVersion; @Test - public void testInitEngine() throws Exception + public void testInitEngine() { assertEquals(FakeTransformEngineWithAllInOne.class.getSimpleName(), transformController.transformEngine.getClass().getSimpleName()); diff --git a/engines/base/src/test/java/org/alfresco/transform/base/TransformControllerTest.java b/engines/base/src/test/java/org/alfresco/transform/base/TransformControllerTest.java index fbd68519..83c50e75 100644 --- a/engines/base/src/test/java/org/alfresco/transform/base/TransformControllerTest.java +++ b/engines/base/src/test/java/org/alfresco/transform/base/TransformControllerTest.java @@ -33,25 +33,43 @@ import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.AppenderBase; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableMap; +import org.alfresco.transform.base.clients.AlfrescoSharedFileStoreClient; import org.alfresco.transform.base.fakes.FakeTransformEngineWithTwoCustomTransformers; import org.alfresco.transform.base.fakes.FakeTransformerPdf2Png; import org.alfresco.transform.base.fakes.FakeTransformerTxT2Pdf; +import org.alfresco.transform.base.model.FileRefEntity; +import org.alfresco.transform.base.model.FileRefResponse; +import org.alfresco.transform.client.model.TransformReply; +import org.alfresco.transform.client.model.TransformRequest; import org.alfresco.transform.config.TransformConfig; +import org.codehaus.plexus.util.FileUtils; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.mockito.stubbing.Answer; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.core.io.Resource; +import org.springframework.core.io.UrlResource; +import org.springframework.http.ResponseEntity; import org.springframework.mock.web.MockMultipartFile; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import java.io.File; import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; import java.util.StringJoiner; +import java.util.UUID; import java.util.stream.Collectors; +import static org.alfresco.transform.base.AbstractBaseTest.getTestFile; import static org.alfresco.transform.common.Mimetype.MIMETYPE_IMAGE_BMP; import static org.alfresco.transform.common.Mimetype.MIMETYPE_PDF; import static org.alfresco.transform.common.Mimetype.MIMETYPE_TEXT_PLAIN; @@ -76,6 +94,12 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; +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.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; @@ -83,7 +107,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** - * Testing base t-engine TransformController functionality. + * Tests the endpoints of the TransformController. Testing of transforms is limit as in that is covered by + * {@link TransformHandlerTest}. * * Also see {@link TransformControllerAllInOneTest}. */ @@ -103,6 +128,29 @@ public class TransformControllerTest protected ObjectMapper objectMapper; @Autowired private String coreVersion; + @TempDir + public File tempDir; + @MockBean + protected AlfrescoSharedFileStoreClient fakeSfsClient; + @BeforeEach + public void fakeSfsClient() + { + final Map sfsRef2File = new HashMap<>(); + when(fakeSfsClient.saveFile(any())).thenAnswer((Answer) invocation -> { + File originalFile = (File) invocation.getArguments()[0]; + + // Make a copy as the original might get deleted + File fileCopy = new File(tempDir, originalFile.getName()+"copy"); + FileUtils.copyFile(originalFile, fileCopy); + + String fileRef = UUID.randomUUID().toString(); + sfsRef2File.put(fileRef, fileCopy); + return new FileRefResponse(new FileRefEntity(fileRef)); + }); + when(fakeSfsClient.retrieveFile(any())).thenAnswer((Answer) invocation -> + ResponseEntity.ok().header(CONTENT_DISPOSITION,"attachment; filename*=UTF-8''transform.tmp") + .body((Resource) new UrlResource(sfsRef2File.get(invocation.getArguments()[0]).toURI()))); + } @Test public void testInitEngine() throws Exception @@ -228,6 +276,7 @@ public class TransformControllerTest TransformConfig config = objectMapper.readValue( mockMvc.perform(MockMvcRequestBuilders.get(url)) .andExpect(status().isOk()) + .andExpect(header().string(CONTENT_TYPE, APPLICATION_JSON_VALUE)) .andReturn() .getResponse() .getContentAsString(), TransformConfig.class); @@ -248,7 +297,44 @@ public class TransformControllerTest } @Test - public void testTransformEndpoint() throws Exception + public void testTransformEndpointThatUsesTransformRequests() throws Exception + { + File sourceFile = getTestFile("quick.txt", true, tempDir); + String sourceFileRef = fakeSfsClient.saveFile(sourceFile).getEntry().getFileRef(); + + TransformRequest transformRequest = TransformRequest.builder() + .withRequestId("1") + .withSchema(1) + .withClientData("Alfresco Digital Business Platform") +// .withTransformRequestOptions(ImmutableMap.of(DIRECT_ACCESS_URL, "file://"+sourceFile.toPath())) + .withSourceReference(sourceFileRef) + .withSourceMediaType(MIMETYPE_TEXT_PLAIN) + .withSourceSize(sourceFile.length()) + .withTargetMediaType(MIMETYPE_PDF) + .withInternalContextForTransformEngineTests() + .build(); + + String transformRequestJson = objectMapper.writeValueAsString(transformRequest); + String transformReplyJson = mockMvc + .perform(MockMvcRequestBuilders + .post(ENDPOINT_TRANSFORM) + .header(ACCEPT, APPLICATION_JSON_VALUE) + .header(CONTENT_TYPE, APPLICATION_JSON_VALUE) + .content(transformRequestJson)) + .andExpect(status().is(CREATED.value())) + .andReturn().getResponse().getContentAsString(); + TransformReply transformReply = objectMapper.readValue(transformReplyJson, TransformReply.class); + String newValue = new String(fakeSfsClient.retrieveFile(transformReply.getTargetReference()).getBody() + .getInputStream().readAllBytes(), StandardCharsets.UTF_8); + + assertEquals(transformRequest.getRequestId(), transformReply.getRequestId()); + assertEquals(transformRequest.getClientData(), transformReply.getClientData()); + assertEquals(transformRequest.getSchema(), transformReply.getSchema()); + assertEquals("Original Text -> TxT2Pdf()", newValue); + } + + @Test + public void testTransformEndpointThatUploadsAndDownloadsContent() throws Exception { MvcResult mvcResult = mockMvc.perform( MockMvcRequestBuilders.multipart(ENDPOINT_TRANSFORM) @@ -268,7 +354,7 @@ public class TransformControllerTest } @Test - public void testTestTransformEndpointConvertsRequestParameters() throws Exception + public void testTestTransformEndpointWhichConvertsRequestParameters() throws Exception { TransformHandler orig = transformController.transformHandler; try diff --git a/engines/base/src/test/java/org/alfresco/transform/base/TransformHandlerTest.java b/engines/base/src/test/java/org/alfresco/transform/base/TransformHandlerTest.java index 8d8a3139..3ee38d8d 100644 --- a/engines/base/src/test/java/org/alfresco/transform/base/TransformHandlerTest.java +++ b/engines/base/src/test/java/org/alfresco/transform/base/TransformHandlerTest.java @@ -26,9 +26,34 @@ */ package org.alfresco.transform.base; +import org.alfresco.transform.client.model.TransformReply; +import org.alfresco.transform.client.model.TransformRequest; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import java.io.File; +import java.util.Map; +import java.util.UUID; + +import static org.alfresco.transform.common.RequestParamMap.DIRECT_ACCESS_URL; +import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static org.springframework.http.HttpHeaders.ACCEPT; +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.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * Tests {@link TransformHandler} and {@link TransformProcess}. + */ public class TransformHandlerTest { @Autowired @@ -36,4 +61,64 @@ public class TransformHandlerTest @Autowired private TransformHandler transformHandler; + +// @Test +// public void transformRequestUsingDirectAccessUrlTest() throws Exception +// { +// // Files +// String sourceFileRef = UUID.randomUUID().toString(); +// File sourceFile = getTestFile("quick." + sourceExtension, true); +// String targetFileRef = UUID.randomUUID().toString(); +// +// TransformRequest transformRequest = createTransformRequest(sourceFileRef, sourceFile); +// Map transformRequestOptions = transformRequest.getTransformRequestOptions(); +// +// String directUrl = "file://" + sourceFile.toPath(); +// +// transformRequestOptions.put(DIRECT_ACCESS_URL, directUrl); +// transformRequest.setTransformRequestOptions(transformRequestOptions); +// +// when(alfrescoSharedFileStoreClient.saveFile(any())) +// .thenReturn(new FileRefResponse(new FileRefEntity(targetFileRef))); +// +// // Update the Transformation Request with any specific params before sending it +// updateTransformRequestWithSpecificOptions(transformRequest); +// +// // Serialize and call the transformer +// String tr = objectMapper.writeValueAsString(transformRequest); +// 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); +// +// // Assert the reply +// assertEquals(transformRequest.getRequestId(), transformReply.getRequestId()); +// assertEquals(transformRequest.getClientData(), transformReply.getClientData()); +// assertEquals(transformRequest.getSchema(), transformReply.getSchema()); +// } +// +// @Test +// public void httpTransformRequestUsingDirectAccessUrlTest() throws Exception +// { +// File dauSourceFile = getTestFile("quick." + sourceExtension, true); +// String directUrl = "file://" + dauSourceFile.toPath(); +// +// ResultActions resultActions = mockMvc.perform( +// mockMvcRequest(ENDPOINT_TRANSFORM, null) +// .param("targetExtension", targetExtension) +// .param(DIRECT_ACCESS_URL, directUrl)) +// .andExpect(status().is(OK.value())); +// +// if (expectedTargetFileBytes != null) +// { +// resultActions.andExpect(content().bytes(expectedTargetFileBytes)); +// } +// } } diff --git a/engines/base/src/test/java/org/alfresco/transform/base/TransformStreamHandlerTest.java b/engines/base/src/test/java/org/alfresco/transform/base/TransformStreamHandlerTest.java new file mode 100644 index 00000000..cda388f4 --- /dev/null +++ b/engines/base/src/test/java/org/alfresco/transform/base/TransformStreamHandlerTest.java @@ -0,0 +1,528 @@ +/* + * #%L + * Alfresco Transform Core + * %% + * Copyright (C) 2022 - 2022 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.transform.base; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Tests {@link TransformStreamHandler} and {@link TransformManagerImpl#createSourceFile()} and + * {@link TransformManagerImpl#createTargetFile()} methods. + */ +public class TransformStreamHandlerTest +{ + public static final String ORIGINAL = "Original"; + public static final String CHANGE = " plus some change"; + public static final String EXPECTED = ORIGINAL+ CHANGE; + + TransformManagerImpl transformManager = new TransformManagerImpl(); + @TempDir + public File tempDir; + + private InputStream getSourceInputStreamFromBytes() + { + return new ByteArrayInputStream(ORIGINAL.getBytes(StandardCharsets.ISO_8859_1)); + } + + private OutputStream getOutputStreamToFile(File sourceFile) throws FileNotFoundException + { + return new BufferedOutputStream(new FileOutputStream(sourceFile)); + } + + private InputStream getInputStreamFromFile(File sourceFile) throws FileNotFoundException + { + return new BufferedInputStream(new FileInputStream(sourceFile)); + } + + private File tempFile() throws IOException + { + return File.createTempFile("temp_", null, tempDir); + } + + private void write(File file, String text) throws IOException + { + try (OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file))) + { + write(outputStream, text); + } + } + + private void write(OutputStream outputStream, String text) throws IOException + { + byte[] bytes = text.getBytes(StandardCharsets.ISO_8859_1); + outputStream.write(bytes, 0, bytes.length); + } + + private String read(File file) throws IOException + { + try (InputStream inputStream = new BufferedInputStream(new FileInputStream(file))) + { + return read(inputStream); + } + } + + private String read(InputStream inputStream) throws IOException + { + return new String(inputStream.readAllBytes(), StandardCharsets.ISO_8859_1); + } + + private String read(ByteArrayOutputStream outputStream) + { + return outputStream.toString(StandardCharsets.ISO_8859_1); + } + + private void closeInputStreamWithoutException(InputStream inputStream) + { + if (inputStream != null) + { + try + { + inputStream.close(); + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } + } + + @Test + public void testStartWithInputStream() throws Exception + { + try (InputStream inputStream = getSourceInputStreamFromBytes(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) + { + transformManager.setInputStream(inputStream); + OutputStream outputStreamLengthRecorder = transformManager.setOutputStream(outputStream); + + write(outputStreamLengthRecorder, read(inputStream)+CHANGE); + + transformManager.copyTargetFileToOutputStream(); + transformManager.getOutputStream().close(); + closeInputStreamWithoutException(inputStream); + transformManager.deleteSourceFile(); + transformManager.deleteTargetFile(); + + assertEquals(EXPECTED, read(outputStream)); + assertEquals(EXPECTED.length(), transformManager.getOutputLength()); + } + } + + @Test + public void testStartWithInputStreamAndCallCreateSourceFile() throws Exception + { + try (InputStream inputStream = getSourceInputStreamFromBytes(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) + { + transformManager.setInputStream(inputStream); + OutputStream outputStreamLengthRecorder = transformManager.setOutputStream(outputStream); + + File sourceFileCreatedByTransform = transformManager.createSourceFile(); + assertTrue(sourceFileCreatedByTransform.exists()); + write(outputStreamLengthRecorder, read(sourceFileCreatedByTransform)+CHANGE); + + transformManager.copyTargetFileToOutputStream(); + transformManager.getOutputStream().close(); + closeInputStreamWithoutException(inputStream); + transformManager.deleteSourceFile(); + transformManager.deleteTargetFile(); + + assertEquals(EXPECTED, read(outputStream)); + assertEquals(EXPECTED.length(), transformManager.getOutputLength()); + assertFalse(sourceFileCreatedByTransform.exists()); + } + } + + @Test + public void testStartWithSourceFile() throws Exception + { + File sourceFile = tempFile(); + write(sourceFile, ORIGINAL); + transformManager.setSourceFile(sourceFile); + + try (InputStream inputStream = new BufferedInputStream(new FileInputStream(sourceFile)); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) + { + transformManager.setInputStream(inputStream); + OutputStream outputStreamLengthRecorder = transformManager.setOutputStream(outputStream); + + write(outputStreamLengthRecorder, read(inputStream)+CHANGE); + + transformManager.copyTargetFileToOutputStream(); + closeInputStreamWithoutException(inputStream); + transformManager.getOutputStream().close(); + transformManager.deleteSourceFile(); + transformManager.deleteTargetFile(); + + assertEquals(EXPECTED, read(outputStream)); + assertEquals(EXPECTED.length(), transformManager.getOutputLength()); + assertFalse(sourceFile.exists()); + } + } + + @Test + public void testStartWithSourceFileAndCallCreateSourceFile() throws Exception + { + File sourceFile = tempFile(); + write(sourceFile, ORIGINAL); + transformManager.setSourceFile(sourceFile); + + try (InputStream inputStream = new BufferedInputStream(new FileInputStream(sourceFile)); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) + { + transformManager.setInputStream(inputStream); + OutputStream outputStreamLengthRecorder = transformManager.setOutputStream(outputStream); + + File sourceFileCreatedByTransform = transformManager.createSourceFile(); + assertEquals(sourceFile, sourceFileCreatedByTransform); + write(outputStreamLengthRecorder, read(sourceFileCreatedByTransform)+CHANGE); + + transformManager.copyTargetFileToOutputStream(); + closeInputStreamWithoutException(inputStream); + transformManager.getOutputStream().close(); + transformManager.deleteSourceFile(); + transformManager.deleteTargetFile(); + + assertEquals(EXPECTED, read(outputStream)); + assertEquals(EXPECTED.length(), transformManager.getOutputLength()); + assertFalse(sourceFile.exists()); + } + } + + @Test + public void testStartWithOutputStream() + { + // Do nothing. Same as testUsingInputStream() which just uses the outputStream + } + + @Test + public void testStartWithOutputStreamAndCallCreateTargetFile() throws Exception + { + try (InputStream inputStream = getSourceInputStreamFromBytes(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) + { + transformManager.setInputStream(inputStream); + transformManager.setOutputStream(outputStream); + + File targetFileCreatedByTransform = transformManager.createTargetFile(); + assertTrue(targetFileCreatedByTransform.exists()); + write(targetFileCreatedByTransform, read(inputStream)+CHANGE); + + transformManager.copyTargetFileToOutputStream(); + transformManager.getOutputStream().close(); + closeInputStreamWithoutException(inputStream); + transformManager.deleteSourceFile(); + transformManager.deleteTargetFile(); + + assertEquals(EXPECTED, read(outputStream)); + assertEquals(EXPECTED.length(), transformManager.getOutputLength()); + assertFalse(targetFileCreatedByTransform.exists()); + } + } + + @Test + public void testStartWithTargetFile() throws Exception + { + File targetFile = tempFile(); + transformManager.setTargetFile(targetFile); + + try (InputStream inputStream = getSourceInputStreamFromBytes(); + OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(targetFile))) + { + transformManager.setInputStream(inputStream); + OutputStream outputStreamLengthRecorder = transformManager.setOutputStream(outputStream); + + write(outputStreamLengthRecorder, read(inputStream)+CHANGE); + + transformManager.copyTargetFileToOutputStream(); + transformManager.getOutputStream().close(); + closeInputStreamWithoutException(inputStream); + String actual = read(targetFile); + transformManager.deleteSourceFile(); + transformManager.deleteTargetFile(); + + assertEquals(EXPECTED, actual); + assertEquals(EXPECTED.length(), transformManager.getOutputLength()); + assertFalse(targetFile.exists()); + } + } + + @Test + public void testStartWithTargetFileAndCallCreateTargetFile() throws Exception + { + File targetFile = tempFile(); + transformManager.setTargetFile(targetFile); + + try (InputStream inputStream = getSourceInputStreamFromBytes(); + OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(targetFile))) + { + transformManager.setInputStream(inputStream); + transformManager.setOutputStream(outputStream); + + File targetFileCreatedByTransform = transformManager.createTargetFile(); + assertEquals(targetFile, targetFileCreatedByTransform); + write(targetFileCreatedByTransform, read(inputStream)+CHANGE); + + transformManager.copyTargetFileToOutputStream(); + transformManager.getOutputStream().close(); + closeInputStreamWithoutException(inputStream); + String actual = read(targetFile); + transformManager.deleteSourceFile(); + transformManager.deleteTargetFile(); + + assertEquals(EXPECTED, actual); + assertEquals(EXPECTED.length(), transformManager.getOutputLength()); + assertFalse(targetFile.exists()); + } + } + + @Test + public void testHandleHttpRequestApproachUsingSourceAndTargetStreams() + { + // Do nothing. Same as testUsingInputStream() which uses inputStream and outputStream + } + + @Test + public void testHandleProbeRequestApproachUsingSourceAndTargetFilesButKeepingTheTarget() throws Exception + { + File targetFile = tempFile(); + File sourceFile = tempFile(); + write(sourceFile, ORIGINAL); + transformManager.setSourceFile(sourceFile); + transformManager.keepTargetFile(); + + try (InputStream inputStream = new BufferedInputStream(new FileInputStream(sourceFile)); + OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(targetFile))) + { + transformManager.setInputStream(inputStream); + OutputStream outputStreamLengthRecorder = transformManager.setOutputStream(outputStream); + + write(outputStreamLengthRecorder, read(inputStream)+CHANGE); + + transformManager.copyTargetFileToOutputStream(); + closeInputStreamWithoutException(inputStream); + transformManager.getOutputStream().close(); + transformManager.deleteSourceFile(); + transformManager.deleteTargetFile(); + + assertEquals(EXPECTED, read(targetFile)); + assertEquals(EXPECTED.length(), transformManager.getOutputLength()); + assertFalse(sourceFile.exists()); + assertTrue(targetFile.exists()); + } + } + + @Test + public void testHandleMessageRequestApproachUsingSourceAndTargetFiles() throws Exception + { + File targetFile = tempFile(); + File sourceFile = tempFile(); + write(sourceFile, ORIGINAL); + transformManager.setSourceFile(sourceFile); + transformManager.setTargetFile(targetFile); + + try (InputStream inputStream = new BufferedInputStream(new FileInputStream(sourceFile)); + OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(targetFile))) + { + transformManager.setInputStream(inputStream); + OutputStream outputStreamLengthRecorder = transformManager.setOutputStream(outputStream); + + write(outputStreamLengthRecorder, read(inputStream)+CHANGE); + + transformManager.copyTargetFileToOutputStream(); + closeInputStreamWithoutException(inputStream); + transformManager.getOutputStream().close(); + String actual = read(targetFile); + transformManager.deleteSourceFile(); + transformManager.deleteTargetFile(); + + assertEquals(EXPECTED, actual); + assertEquals(EXPECTED.length(), transformManager.getOutputLength()); + assertFalse(sourceFile.exists()); + assertFalse(targetFile.exists()); + } + } + + @Test + public void testHandleMessageRequestApproachUsingInputStreamAndTargetFile() throws Exception + { + File targetFile = tempFile(); + transformManager.setTargetFile(targetFile); + + try (InputStream inputStream = getSourceInputStreamFromBytes(); + OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(targetFile))) + { + transformManager.setInputStream(inputStream); + OutputStream outputStreamLengthRecorder = transformManager.setOutputStream(outputStream); + + write(outputStreamLengthRecorder, read(inputStream)+CHANGE); + + transformManager.copyTargetFileToOutputStream(); + closeInputStreamWithoutException(inputStream); + transformManager.getOutputStream().close(); + String actual = read(targetFile); + transformManager.deleteSourceFile(); + transformManager.deleteTargetFile(); + + assertEquals(EXPECTED, actual); + assertEquals(EXPECTED.length(), transformManager.getOutputLength()); + assertFalse(targetFile.exists()); + } + } + + private abstract class FakeTransformStreamHandler extends TransformStreamHandler + { + @Override + public void handleTransformRequest() throws Exception + { + init(); + handleTransform(null); + } + + @Override + protected void transform(CustomTransformer customTransformer) throws Exception + { + write(outputStream, read(inputStream)+CHANGE); + } + } + + @Test + public void testSimulatedHandleHttpRequest() throws Exception + { + try (ByteArrayOutputStream os = new ByteArrayOutputStream()) + { + new FakeTransformStreamHandler() + { + @Override + protected InputStream getInputStream() + { + return getSourceInputStreamFromBytes(); + } + + @Override + protected OutputStream getOutputStream() + { + return os; + } + }.handleTransformRequest(); + } + } + + @Test + public void testSimulatedHandleProbeRequest() throws Exception + { + File targetFile = tempFile(); + File sourceFile = tempFile(); + write(sourceFile, ORIGINAL); + + new FakeTransformStreamHandler() + { + @Override + protected void init() throws IOException + { + transformManager.setSourceFile(sourceFile); + transformManager.setTargetFile(targetFile); + transformManager.keepTargetFile(); + super.init(); + } + + @Override + protected InputStream getInputStream() throws IOException + { + return getInputStreamFromFile(sourceFile); + } + + @Override + protected OutputStream getOutputStream() throws IOException + { + return getOutputStreamToFile(targetFile); + } + }.handleTransformRequest(); + } + + @Test + public void testSimulatedHandleMessageRequestUsingSharedFileStore() throws Exception + { + File targetFile = tempFile(); + File sourceFile = tempFile(); + write(sourceFile, ORIGINAL); + + new FakeTransformStreamHandler() + { + @Override + protected InputStream getInputStream() throws IOException + { + return getInputStreamFromFile(sourceFile); + } + + @Override + protected OutputStream getOutputStream() throws IOException + { + return getOutputStreamToFile(targetFile); + } + }.handleTransformRequest(); + } + + @Test + public void testSimulatedHandleMessageRequestUsingDirectAccessUrl() throws Exception + { + File targetFile = tempFile(); + + new FakeTransformStreamHandler() + { + @Override + protected InputStream getInputStream() + { + return getSourceInputStreamFromBytes(); + } + + @Override + protected OutputStream getOutputStream() + throws FileNotFoundException + { + return getOutputStreamToFile(targetFile); + } + }.handleTransformRequest(); + } +} diff --git a/engines/imagemagick/src/test/java/org/alfresco/transform/imagemagick/ImageMagickQueueTest.java b/engines/imagemagick/src/test/java/org/alfresco/transform/imagemagick/ImageMagickQueueTest.java index 4ccf1a21..e33f81a0 100644 --- a/engines/imagemagick/src/test/java/org/alfresco/transform/imagemagick/ImageMagickQueueTest.java +++ b/engines/imagemagick/src/test/java/org/alfresco/transform/imagemagick/ImageMagickQueueTest.java @@ -53,6 +53,7 @@ public class ImageMagickQueueTest extends AbstractQueueTest .withClientData("ACS") .withSourceReference(UUID.randomUUID().toString()) .withSourceSize(32L) + .withInternalContextForTransformEngineTests() .build(); } } diff --git a/engines/imagemagick/src/test/java/org/alfresco/transform/imagemagick/ImageMagickTest.java b/engines/imagemagick/src/test/java/org/alfresco/transform/imagemagick/ImageMagickTest.java index 674170b1..6a8fcc7e 100644 --- a/engines/imagemagick/src/test/java/org/alfresco/transform/imagemagick/ImageMagickTest.java +++ b/engines/imagemagick/src/test/java/org/alfresco/transform/imagemagick/ImageMagickTest.java @@ -132,12 +132,6 @@ public class ImageMagickTest extends AbstractBaseTest mockTransformCommand("jpg", "png", "image/jpg", true); } - @Override - public String getEngineConfigName() - { - return ENGINE_CONFIG_NAME; - } - @Override protected void mockTransformCommand(String sourceExtension, String targetExtension, String sourceMimetype, diff --git a/engines/libreoffice/src/test/java/org/alfresco/transform/libreoffice/LibreOfficeQueueTest.java b/engines/libreoffice/src/test/java/org/alfresco/transform/libreoffice/LibreOfficeQueueTest.java index eaccb949..9d175d5f 100644 --- a/engines/libreoffice/src/test/java/org/alfresco/transform/libreoffice/LibreOfficeQueueTest.java +++ b/engines/libreoffice/src/test/java/org/alfresco/transform/libreoffice/LibreOfficeQueueTest.java @@ -52,6 +52,7 @@ public class LibreOfficeQueueTest extends AbstractQueueTest .withClientData("ACS") .withSourceReference(UUID.randomUUID().toString()) .withSourceSize(32L) + .withInternalContextForTransformEngineTests() .build(); } } diff --git a/engines/libreoffice/src/test/java/org/alfresco/transform/libreoffice/LibreOfficeTest.java b/engines/libreoffice/src/test/java/org/alfresco/transform/libreoffice/LibreOfficeTest.java index 6eff8fa4..45894fac 100644 --- a/engines/libreoffice/src/test/java/org/alfresco/transform/libreoffice/LibreOfficeTest.java +++ b/engines/libreoffice/src/test/java/org/alfresco/transform/libreoffice/LibreOfficeTest.java @@ -168,12 +168,6 @@ public class LibreOfficeTest extends AbstractBaseTest // ReflectionTestUtils.setField(controller, "javaExecutor", javaExecutor); // } - @Override - public String getEngineConfigName() - { - return ENGINE_CONFIG_NAME; - } - @Override protected void mockTransformCommand(String sourceExtension, String targetExtension, String sourceMimetype, boolean readTargetFileBytes) diff --git a/engines/misc/src/main/java/org/alfresco/transform/misc/metadataExtractors/RFC822MetadataExtractor.java b/engines/misc/src/main/java/org/alfresco/transform/misc/metadataExtractors/RFC822MetadataExtractor.java index 32575ccd..2550e973 100644 --- a/engines/misc/src/main/java/org/alfresco/transform/misc/metadataExtractors/RFC822MetadataExtractor.java +++ b/engines/misc/src/main/java/org/alfresco/transform/misc/metadataExtractors/RFC822MetadataExtractor.java @@ -31,6 +31,7 @@ import org.alfresco.transform.base.TransformManager; import org.alfresco.transform.base.metadataExtractors.AbstractMetadataExtractor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; import javax.mail.Header; import javax.mail.internet.InternetAddress; @@ -71,6 +72,7 @@ import static org.alfresco.transform.base.metadataExtractors.AbstractMetadataExt * @author Derek Hulley * @author adavis */ +@Component public class RFC822MetadataExtractor extends AbstractMetadataExtractor implements CustomTransformer { private static final Logger logger = LoggerFactory.getLogger(RFC822MetadataExtractor.class); diff --git a/engines/misc/src/test/java/org/alfresco/transform/misc/MiscQueueTest.java b/engines/misc/src/test/java/org/alfresco/transform/misc/MiscQueueTest.java index 3f474754..1c41f287 100644 --- a/engines/misc/src/test/java/org/alfresco/transform/misc/MiscQueueTest.java +++ b/engines/misc/src/test/java/org/alfresco/transform/misc/MiscQueueTest.java @@ -48,6 +48,8 @@ public class MiscQueueTest extends AbstractQueueTest .withSchema(1) .withClientData("ACS") .withSourceReference(UUID.randomUUID().toString()) - .withSourceSize(32L).build(); + .withSourceSize(32L) + .withInternalContextForTransformEngineTests() + .build(); } } diff --git a/engines/misc/src/test/java/org/alfresco/transform/misc/MiscTest.java b/engines/misc/src/test/java/org/alfresco/transform/misc/MiscTest.java index 6238d2ef..79bf130c 100644 --- a/engines/misc/src/test/java/org/alfresco/transform/misc/MiscTest.java +++ b/engines/misc/src/test/java/org/alfresco/transform/misc/MiscTest.java @@ -53,7 +53,6 @@ import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -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.request; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -82,12 +81,6 @@ public class MiscTest extends AbstractBaseTest sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype, sourceFileBytes); } - @Override - public String getEngineConfigName() - { - return ENGINE_CONFIG_NAME; - } - @Override protected void mockTransformCommand(String sourceExtension, String targetExtension, String sourceMimetype, boolean readTargetFileBytes) diff --git a/engines/pdfrenderer/src/test/java/org/alfresco/transform/pdfrenderer/PdfRendererQueueTest.java b/engines/pdfrenderer/src/test/java/org/alfresco/transform/pdfrenderer/PdfRendererQueueTest.java index 85465cdc..bb68d6b2 100644 --- a/engines/pdfrenderer/src/test/java/org/alfresco/transform/pdfrenderer/PdfRendererQueueTest.java +++ b/engines/pdfrenderer/src/test/java/org/alfresco/transform/pdfrenderer/PdfRendererQueueTest.java @@ -52,6 +52,8 @@ public class PdfRendererQueueTest extends AbstractQueueTest .withSchema(1) .withClientData("ACS") .withSourceReference(UUID.randomUUID().toString()) - .withSourceSize(32L).build(); + .withSourceSize(32L) + .withInternalContextForTransformEngineTests() + .build(); } } diff --git a/engines/pdfrenderer/src/test/java/org/alfresco/transform/pdfrenderer/PdfRendererTest.java b/engines/pdfrenderer/src/test/java/org/alfresco/transform/pdfrenderer/PdfRendererTest.java index ae4b51fd..a3e1af8f 100644 --- a/engines/pdfrenderer/src/test/java/org/alfresco/transform/pdfrenderer/PdfRendererTest.java +++ b/engines/pdfrenderer/src/test/java/org/alfresco/transform/pdfrenderer/PdfRendererTest.java @@ -122,12 +122,6 @@ public class PdfRendererTest extends AbstractBaseTest ReflectionTestUtils.setField(controller, "commandExecutor", commandExecutor); } - @Override - public String getEngineConfigName() - { - return ENGINE_CONFIG_NAME; - } - @Override public void mockTransformCommand(String sourceExtension, String targetExtension, String sourceMimetype, diff --git a/engines/pdfrenderer/src/test/java/org/alfresco/transform/pdfrenderer/AlfrescoPdfRendererTransformationIT.java b/engines/pdfrenderer/src/test/java/org/alfresco/transform/pdfrenderer/PdfRendererTransformationIT.java similarity index 96% rename from engines/pdfrenderer/src/test/java/org/alfresco/transform/pdfrenderer/AlfrescoPdfRendererTransformationIT.java rename to engines/pdfrenderer/src/test/java/org/alfresco/transform/pdfrenderer/PdfRendererTransformationIT.java index 7262acb4..a84fc8b3 100644 --- a/engines/pdfrenderer/src/test/java/org/alfresco/transform/pdfrenderer/AlfrescoPdfRendererTransformationIT.java +++ b/engines/pdfrenderer/src/test/java/org/alfresco/transform/pdfrenderer/PdfRendererTransformationIT.java @@ -49,10 +49,9 @@ import org.springframework.http.ResponseEntity; /** * @author Cezar Leahu */ -public class AlfrescoPdfRendererTransformationIT +public class PdfRendererTransformationIT { - private static final Logger logger = LoggerFactory.getLogger( - AlfrescoPdfRendererTransformationIT.class); + private static final Logger logger = LoggerFactory.getLogger(PdfRendererTransformationIT.class); private static final String ENGINE_URL = "http://localhost:8090"; private static final Map TEST_FILES = Stream.of( diff --git a/engines/tika/src/test/java/org/alfresco/transform/tika/TikaQueueTest.java b/engines/tika/src/test/java/org/alfresco/transform/tika/TikaQueueTest.java index 8c75c470..36eef048 100644 --- a/engines/tika/src/test/java/org/alfresco/transform/tika/TikaQueueTest.java +++ b/engines/tika/src/test/java/org/alfresco/transform/tika/TikaQueueTest.java @@ -52,6 +52,8 @@ public class TikaQueueTest extends AbstractQueueTest .withSchema(1) .withClientData("ACS") .withSourceReference(UUID.randomUUID().toString()) - .withSourceSize(32L).build(); + .withSourceSize(32L) + .withInternalContextForTransformEngineTests() + .build(); } } diff --git a/engines/tika/src/test/java/org/alfresco/transform/tika/TikaTest.java b/engines/tika/src/test/java/org/alfresco/transform/tika/TikaTest.java index 2aa7b2fa..fe05c669 100644 --- a/engines/tika/src/test/java/org/alfresco/transform/tika/TikaTest.java +++ b/engines/tika/src/test/java/org/alfresco/transform/tika/TikaTest.java @@ -30,7 +30,6 @@ import org.alfresco.transform.base.AbstractBaseTest; import org.alfresco.transform.base.executors.RuntimeExec; import org.alfresco.transform.base.model.FileRefEntity; import org.alfresco.transform.base.model.FileRefResponse; -import org.alfresco.transform.base.probes.ProbeTransform; import org.alfresco.transform.client.model.TransformReply; import org.alfresco.transform.client.model.TransformRequest; import org.apache.poi.ooxml.POIXMLProperties; @@ -45,7 +44,6 @@ import org.springframework.core.io.Resource; import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; import org.springframework.mock.web.MockMultipartFile; -import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; @@ -145,12 +143,6 @@ public class TikaTest extends AbstractBaseTest targetMimetype = MIMETYPE_TEXT_PLAIN; } - @Override - public String getEngineConfigName() - { - return ENGINE_CONFIG_NAME; - } - @Override protected void mockTransformCommand(String sourceExtension, String targetExtension, String sourceMimetype, @@ -166,57 +158,7 @@ public class TikaTest extends AbstractBaseTest expectedTargetFileBytes = readTargetFileBytes ? readTestFile(targetExtension) : null; sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype, sourceFileBytes); - when(mockTransformCommand.execute(any(), anyLong())).thenAnswer( - (Answer) invocation -> { - Map actualProperties = invocation.getArgument(0); - assertEquals(3, actualProperties.size(),"There should be 3 properties"); - - String actualOptions = actualProperties.get("options"); - String actualSource = actualProperties.get("source"); - String actualTarget = actualProperties.get("target"); - String actualTargetExtension = getFilenameExtension(actualTarget); - - assertNotNull(actualSource); - assertNotNull(actualTarget); - if (expectedSourceSuffix != null) - { - assertTrue(actualSource.endsWith(expectedSourceSuffix), - "The source file \"" + actualSource + "\" should have ended in \"" + expectedSourceSuffix + "\""); - actualSource = actualSource.substring(0, - actualSource.length() - expectedSourceSuffix.length()); - } - - assertNotNull(actualOptions); - if (expectedOptions != null) - { - Assertions.assertEquals(expectedOptions, actualOptions, "expectedOptions"); - } - - Long actualTimeout = invocation.getArgument(1); - assertNotNull(actualTimeout); - if (expectedTimeout != null) - { - Assertions.assertEquals(expectedTimeout, actualTimeout, "expectedTimeout"); - } - - // Copy a test file into the target file location if it exists - int i = actualTarget.lastIndexOf('_'); - if (i >= 0) - { - String testFilename = actualTarget.substring(i + 1); - File testFile = getTestFile(testFilename, false); - File targetFile = new File(actualTarget); - generateTargetFileFromResourceFile(actualTargetExtension, testFile, - targetFile); - } - - // Check the supplied source file has not been changed. - byte[] actualSourceFileBytes = readAllBytes(new File(actualSource).toPath()); - Assertions.assertArrayEquals(sourceFileBytes, actualSourceFileBytes, - "Source file is not the same"); - - return mockExecutionResult; - }); + // Tika transform is not mocked. It is run for real. when(mockExecutionResult.getExitValue()).thenReturn(0); when(mockExecutionResult.getStdErr()).thenReturn("STDERROR"); @@ -295,22 +237,6 @@ public class TikaTest extends AbstractBaseTest super.noExtensionSourceFilenameTest(); } - @Test - @Override - public void badSourceFilenameTest() throws Exception - { - mockTransformCommand(PDF, TXT, MIMETYPE_PDF, true); - super.badSourceFilenameTest(); - } - - @Test - @Override - public void blankSourceFilenameTest() throws Exception - { - mockTransformCommand(PDF, TXT, MIMETYPE_PDF, true); - super.blankSourceFilenameTest(); - } - @Test @Override public void calculateMaxTime() throws Exception diff --git a/model/src/main/java/org/alfresco/transform/client/model/TransformRequest.java b/model/src/main/java/org/alfresco/transform/client/model/TransformRequest.java index ebb5df46..89ad0a01 100644 --- a/model/src/main/java/org/alfresco/transform/client/model/TransformRequest.java +++ b/model/src/main/java/org/alfresco/transform/client/model/TransformRequest.java @@ -21,11 +21,18 @@ */ package org.alfresco.transform.client.model; +import org.alfresco.transform.common.ExtensionService; +import org.alfresco.transform.messages.TransformStack; + import java.io.Serializable; import java.util.HashMap; import java.util.Map; import java.util.Objects; +import static org.alfresco.transform.messages.TransformStack.PIPELINE_FLAG; +import static org.alfresco.transform.messages.TransformStack.levelBuilder; +import static org.alfresco.transform.messages.TransformStack.setInitialTransformRequestOptions; + // This class is in the package org.alfresco.transform.messages in HxP because that is more readable, but in // org.alfresco.transform.client.model in Alfresco for backward compatibility. public class TransformRequest implements Serializable @@ -189,6 +196,25 @@ public class TransformRequest implements Serializable '}'; } + /** + * Sets up the internal context structure when a client request is initially received by the router, + * so that we don't have to keep checking if bits of it are initialised. Prior to making this call, + * the id, sourceMimetypes, targetMimetype, transformRequestOptions and sourceReference should have + * been set, if they are to be set. + */ + public TransformRequest initialiseContextWhenReceivedByRouter() + { + setInternalContext(InternalContext.initialise(getInternalContext())); + setTargetExtension(ExtensionService.getExtensionForTargetMimetype(getTargetMediaType(), + getSourceMediaType())); + getInternalContext().getMultiStep().setInitialRequestId(getRequestId()); + getInternalContext().getMultiStep().setInitialSourceMediaType(getSourceMediaType()); + getInternalContext().setTransformRequestOptions(getTransformRequestOptions()); + setInitialTransformRequestOptions(getInternalContext(), getTransformRequestOptions()); + TransformStack.setInitialSourceReference(getInternalContext(), getSourceReference()); + return this; + } + public static Builder builder() { return new Builder(); @@ -267,6 +293,14 @@ public class TransformRequest implements Serializable return this; } + public Builder withInternalContextForTransformEngineTests() + { + request.initialiseContextWhenReceivedByRouter(); + TransformStack.addTransformLevel(request.internalContext, levelBuilder(PIPELINE_FLAG) + .withStep("dummyTransformerName", request.sourceMediaType, request.targetMediaType)); + return this; + } + public TransformRequest build() { return request; diff --git a/model/src/test/java/org/alfresco/transform/messages/TransformStackTest.java b/model/src/test/java/org/alfresco/transform/messages/TransformStackTest.java index 7f8c9151..546c1410 100644 --- a/model/src/test/java/org/alfresco/transform/messages/TransformStackTest.java +++ b/model/src/test/java/org/alfresco/transform/messages/TransformStackTest.java @@ -88,7 +88,7 @@ class TransformStackTest { MockitoAnnotations.openMocks(this); - // Repeat what is done by Router.initialiseContext + // Repeat what is done by Router.initialiseContextWhenReceivedByRouter internalContext.setMultiStep(new MultiStep()); internalContext.getMultiStep().setTransformsToBeDone(new ArrayList<>()); TransformStack.setInitialTransformRequestOptions(internalContext, options); diff --git a/model/src/test/java/org/alfresco/transform/registry/CombinedTransformConfigTest.java b/model/src/test/java/org/alfresco/transform/registry/CombinedTransformConfigTest.java index bfef160e..5697e5e8 100644 --- a/model/src/test/java/org/alfresco/transform/registry/CombinedTransformConfigTest.java +++ b/model/src/test/java/org/alfresco/transform/registry/CombinedTransformConfigTest.java @@ -21,15 +21,20 @@ */ package org.alfresco.transform.registry; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import org.alfresco.transform.common.TransformConfigResourceReader; import org.alfresco.transform.config.SupportedSourceAndTarget; import org.alfresco.transform.config.TransformConfig; import org.alfresco.transform.config.TransformStep; import org.alfresco.transform.config.Transformer; import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import java.io.IOException; +import java.io.InputStream; import java.util.List; import java.util.Set; @@ -201,7 +206,16 @@ public class CombinedTransformConfigTest } }; - private final TestTransformRegistry registry = new TestTransformRegistry(); + private final FakeTransformRegistry registry = new FakeTransformRegistry(); + + private static final ObjectMapper objectMapper = new ObjectMapper(); + + private TransformConfig readTransformConfigFromResource(String filename) throws IOException + { + return objectMapper.readValue( + getClass().getClassLoader().getResourceAsStream(filename), + TransformConfig.class); + } private String expectedWildcardError(String errorReason) { @@ -889,8 +903,62 @@ public class CombinedTransformConfigTest config.addTransformConfig(transformConfig, READ_FROM_B, BASE_URL_B, registry); config.combineTransformerConfig(registry); - String expected = expectedWildcardError("the step transforms don't support any"); + assertEquals(expectedWildcardError("the step transforms don't support any"), registry.errorMessages.get(0)); + } + + @Test + public void testJsonComplete() throws Exception + { + TransformConfig transformConfig = readTransformConfigFromResource("engine_config_complete.json"); + + config.addTransformConfig(transformConfig, READ_FROM_B, BASE_URL_B, registry); + config.combineTransformerConfig(registry); + TransformConfig combinedTransformConfig = config.buildTransformConfig(); + + assertEquals(0, registry.errorMessages.size()); + assertEquals(1, combinedTransformConfig.getTransformers().size()); + assertEquals(1, combinedTransformConfig.getTransformOptions().size()); + } + + @Test + public void testJsonDuplicateOptionsAndSupportedMimetypes() throws Exception + { + TransformConfig transformConfig = readTransformConfigFromResource("engine_config_with_duplicates.json"); + + config.addTransformConfig(transformConfig, READ_FROM_B, BASE_URL_B, registry); + config.combineTransformerConfig(registry); + TransformConfig combinedTransformConfig = config.buildTransformConfig(); + + assertEquals(0, registry.errorMessages.size()); + assertEquals(1, combinedTransformConfig.getTransformers().size()); + assertEquals(1, combinedTransformConfig.getTransformOptions().size()); + } + + @Test + public void testJsonNoOptions() throws Exception + { + TransformConfig transformConfig = readTransformConfigFromResource("engine_config_no_transform_options.json"); + + config.addTransformConfig(transformConfig, READ_FROM_B, BASE_URL_B, registry); + config.combineTransformerConfig(registry); + TransformConfig combinedTransformConfig = config.buildTransformConfig(); + + assertEquals(0, registry.errorMessages.size()); + assertEquals(1, combinedTransformConfig.getTransformers().size()); + assertEquals(0, combinedTransformConfig.getTransformOptions().size()); + } + + @Test + public void testJsonIncompleteNoTransformName() throws Exception + { + TransformConfig transformConfig = readTransformConfigFromResource("engine_config_incomplete.json"); + + config.addTransformConfig(transformConfig, READ_FROM_B, BASE_URL_B, registry); + config.combineTransformerConfig(registry); + TransformConfig combinedTransformConfig = config.buildTransformConfig(); + assertEquals(1, registry.errorMessages.size()); - assertEquals(expected, registry.errorMessages.get(0)); + assertEquals("Transformer names may not be null. Read from readFromB", registry.errorMessages.get(0)); + assertEquals(0, combinedTransformConfig.getTransformers().size()); } } diff --git a/model/src/test/java/org/alfresco/transform/registry/TestTransformRegistry.java b/model/src/test/java/org/alfresco/transform/registry/FakeTransformRegistry.java similarity index 97% rename from model/src/test/java/org/alfresco/transform/registry/TestTransformRegistry.java rename to model/src/test/java/org/alfresco/transform/registry/FakeTransformRegistry.java index a1048e85..2714ed08 100644 --- a/model/src/test/java/org/alfresco/transform/registry/TestTransformRegistry.java +++ b/model/src/test/java/org/alfresco/transform/registry/FakeTransformRegistry.java @@ -33,7 +33,7 @@ import java.util.Set; /** * Helper class for testing an {@link AbstractTransformRegistry}. */ -public class TestTransformRegistry extends AbstractTransformRegistry +public class FakeTransformRegistry extends AbstractTransformRegistry { private static final String READ_FROM_A = "readFromA"; private static final String BASE_URL_B = "baseUrlB"; diff --git a/model/src/test/java/org/alfresco/transform/registry/OverrideTransformConfigTests.java b/model/src/test/java/org/alfresco/transform/registry/OverrideTransformConfigTests.java index 351b48cf..7d7ea875 100644 --- a/model/src/test/java/org/alfresco/transform/registry/OverrideTransformConfigTests.java +++ b/model/src/test/java/org/alfresco/transform/registry/OverrideTransformConfigTests.java @@ -96,7 +96,7 @@ public class OverrideTransformConfigTests private final CombinedTransformConfig config = new CombinedTransformConfig(); - private final TestTransformRegistry registry = new TestTransformRegistry(); + private final FakeTransformRegistry registry = new FakeTransformRegistry(); @Test public void testRemoveTransformers() diff --git a/engines/base/src/test/resources/engine_config_complete.json b/model/src/test/resources/engine_config_complete.json similarity index 100% rename from engines/base/src/test/resources/engine_config_complete.json rename to model/src/test/resources/engine_config_complete.json diff --git a/engines/base/src/test/resources/engine_config_incomplete.json b/model/src/test/resources/engine_config_incomplete.json similarity index 100% rename from engines/base/src/test/resources/engine_config_incomplete.json rename to model/src/test/resources/engine_config_incomplete.json diff --git a/engines/base/src/test/resources/engine_config_no_transform_options.json b/model/src/test/resources/engine_config_no_transform_options.json similarity index 100% rename from engines/base/src/test/resources/engine_config_no_transform_options.json rename to model/src/test/resources/engine_config_no_transform_options.json diff --git a/engines/base/src/test/resources/engine_config_with_duplicates.json b/model/src/test/resources/engine_config_with_duplicates.json similarity index 100% rename from engines/base/src/test/resources/engine_config_with_duplicates.json rename to model/src/test/resources/engine_config_with_duplicates.json