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 988efa15..14eba807 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 @@ -38,6 +38,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.event.EventListener; +import org.springframework.core.io.Resource; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; @@ -52,7 +53,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; import javax.annotation.PostConstruct; import javax.servlet.http.HttpServletRequest; @@ -222,11 +222,11 @@ public class TransformController // 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, - @RequestParam(value = SOURCE_MIMETYPE) String sourceMimetype, - @RequestParam(value = TARGET_MIMETYPE) String targetMimetype, - @RequestParam Map requestParameters) + public ResponseEntity transform(HttpServletRequest request, + @RequestParam(value = FILE, required = false) MultipartFile sourceMultipartFile, + @RequestParam(value = SOURCE_MIMETYPE) String sourceMimetype, + @RequestParam(value = TARGET_MIMETYPE) String targetMimetype, + @RequestParam Map requestParameters) { return transformHandler.handleHttpRequest(request, sourceMultipartFile, sourceMimetype, targetMimetype, requestParameters); @@ -234,7 +234,7 @@ public class TransformController // Used the t-engine's simple html test UI. @PostMapping(value = ENDPOINT_TEST, consumes = MULTIPART_FORM_DATA_VALUE) - public ResponseEntity testTransform(HttpServletRequest request, + public ResponseEntity testTransform(HttpServletRequest request, @RequestParam(value = FILE, required = false) MultipartFile sourceMultipartFile, @RequestParam(value = SOURCE_MIMETYPE, required = false) String sourceMimetype, @RequestParam(value = TARGET_MIMETYPE, required = false) String targetMimetype, 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 885db426..d057ab42 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 @@ -43,8 +43,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; -import org.springframework.http.ContentDisposition; -import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; @@ -52,7 +50,6 @@ import org.springframework.validation.DirectFieldBindingResult; import org.springframework.validation.Errors; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; import javax.annotation.PostConstruct; import javax.jms.Destination; @@ -66,16 +63,17 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import static java.util.stream.Collectors.joining; +import static org.alfresco.transform.base.fs.FileManager.createAttachment; import static org.alfresco.transform.base.fs.FileManager.createTargetFile; import static org.alfresco.transform.base.fs.FileManager.getDirectAccessUrlInputStream; import static org.alfresco.transform.base.fs.FileManager.getMultipartFileInputStream; @@ -185,47 +183,50 @@ public class TransformHandler return transformerDebug; } - public ResponseEntity handleHttpRequest(HttpServletRequest request, + public ResponseEntity handleHttpRequest(HttpServletRequest request, MultipartFile sourceMultipartFile, String sourceMimetype, String targetMimetype, Map requestParameters) { - return createResponseEntity(sourceMimetype, targetMimetype, os -> + AtomicReference> responseEntity = new AtomicReference<>(); + + new TransformProcess(this, sourceMimetype, targetMimetype, requestParameters, + "e" + httpRequestCount.getAndIncrement()) { - new TransformProcess(this, sourceMimetype, targetMimetype, requestParameters, - "e" + httpRequestCount.getAndIncrement()) + @Override + protected void init() throws IOException { - @Override - protected void init() throws IOException - { - transformManager.setRequest(request); - super.init(); - } + transformManager.setRequest(request); + transformManager.setTargetFile(createTargetFile(request, sourceMimetype, targetMimetype)); + transformManager.keepTargetFile(); // Will be deleted in TransformInterceptor.afterCompletion() + super.init(); + } - @Override - protected InputStream getInputStream() - { - return getInputStreamForHandleHttpRequest(requestParameters, sourceMultipartFile); - } + @Override + protected InputStream getInputStream() + { + return getInputStreamForHandleHttpRequest(requestParameters, sourceMultipartFile); + } - @Override - protected long getSourceSize() - { - return -1L; // Ignore for http requests as the Alfresco repo will have checked. - } + @Override + protected OutputStream getOutputStream() throws IOException + { + return getOutputStreamFromFile(transformManager.getTargetFile()); + } - @Override - protected OutputStream getOutputStream() - { - return os; - } + @Override + protected long getSourceSize() + { + return -1L; // Ignore for http requests as the Alfresco repo will have checked. + } - @Override - protected void closeOutputStream() throws IOException - { - // Do nothing as the Spring mvc handles this for HttpServletRequest - } - }.handleTransformRequest(); - }); + protected void sendTransformResponse(TransformManagerImpl transformManager) + { + String extension = ExtensionService.getExtensionForTargetMimetype(targetMimetype, sourceMimetype); + responseEntity.set(createAttachment("transform."+extension, transformManager.getTargetFile())); + } + }.handleTransformRequest(); + + return responseEntity.get(); } public void handleProbRequest(String sourceMimetype, String targetMimetype, Map transformOptions, @@ -274,6 +275,7 @@ public class TransformHandler { checkTransformRequestValid(request, reply); reference = TransformStack.getReference(reply.getInternalContext()); + transformManager.setTargetFile(createTargetFile(null, sourceMimetype, targetMimetype)); super.init(); } @@ -292,8 +294,7 @@ public class TransformHandler @Override protected OutputStream getOutputStream() throws IOException { - File targetFile = transformManager.setTargetFile(createTargetFile(null, sourceMimetype, targetMimetype)); - return getOutputStreamFromFile(targetFile); + return getOutputStreamFromFile(transformManager.getTargetFile()); } protected void sendTransformResponse(TransformManagerImpl transformManager) @@ -537,16 +538,4 @@ public class TransformHandler } return customTransformer; } - - private ResponseEntity createResponseEntity(String sourceMimetype, String targetMimetype, - StreamingResponseBody body) - { - String extension = ExtensionService.getExtensionForTargetMimetype(targetMimetype, sourceMimetype); - HttpHeaders headers = new HttpHeaders(); - headers.setContentDisposition( - ContentDisposition.attachment() - .filename("transform."+ extension, StandardCharsets.UTF_8) - .build()); - return ResponseEntity.ok().headers(headers).body(body); - } } 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 index 9898d7cd..a7f23ffd 100644 --- a/engines/base/src/main/java/org/alfresco/transform/base/TransformProcess.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/TransformProcess.java @@ -122,9 +122,9 @@ abstract class TransformProcess extends TransformStreamHandler LogEntry.setTargetSize(transformManager.getOutputLength()); LogEntry.setStatusCodeAndMessage(OK, "Success"); } + protected void sendTransformResponse(TransformManagerImpl transformManager) { - // Only used in handleMessageRequest(...) } protected void handleTransformException(TransformException e, HttpStatus status) diff --git a/engines/base/src/main/java/org/alfresco/transform/base/fs/FileManager.java b/engines/base/src/main/java/org/alfresco/transform/base/fs/FileManager.java index b1433a7e..1828c0a3 100644 --- a/engines/base/src/main/java/org/alfresco/transform/base/fs/FileManager.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/fs/FileManager.java @@ -30,19 +30,19 @@ import org.alfresco.transform.base.logging.LogEntry; import org.alfresco.transform.common.ExtensionService; import org.alfresco.transform.common.TransformException; import org.springframework.core.io.Resource; -import org.springframework.http.ContentDisposition; +import org.springframework.core.io.UrlResource; import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; +import org.springframework.web.util.UriUtils; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.net.MalformedURLException; import java.net.URL; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.Arrays; @@ -52,6 +52,7 @@ import static org.springframework.http.HttpHeaders.CONTENT_DISPOSITION; import static org.springframework.http.HttpStatus.BAD_REQUEST; import static org.springframework.http.HttpStatus.INSUFFICIENT_STORAGE; import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; +import static org.springframework.util.StringUtils.getFilename; public class FileManager { @@ -118,6 +119,28 @@ public class FileManager } } + private static Resource load(File file) + { + try + { + Resource resource = new UrlResource(file.toURI()); + if (resource.exists() || resource.isReadable()) + { + return resource; + } + else + { + throw new TransformException(INTERNAL_SERVER_ERROR, + "Could not read the target file: " + file.getPath()); + } + } + catch (MalformedURLException e) + { + throw new TransformException(INTERNAL_SERVER_ERROR, + "The target filename was malformed: " + file.getPath(), e); + } + } + public static String getFilenameFromContentDisposition(HttpHeaders headers) { String filename = ""; @@ -190,6 +213,14 @@ public class FileManager } } + public static ResponseEntity createAttachment(String targetFilename, File targetFile) + { + Resource targetResource = load(targetFile); + targetFilename = UriUtils.encodePath(getFilename(targetFilename), "UTF-8"); + return ResponseEntity.ok().header(CONTENT_DISPOSITION, + "attachment; filename*=UTF-8''" + targetFilename).body(targetResource); + } + /** * TempFileProvider - Duplicated and adapted from alfresco-core. */ diff --git a/engines/base/src/main/java/org/alfresco/transform/base/probes/ProbeTransform.java b/engines/base/src/main/java/org/alfresco/transform/base/probes/ProbeTransform.java index c10283a3..f823fcc3 100644 --- a/engines/base/src/main/java/org/alfresco/transform/base/probes/ProbeTransform.java +++ b/engines/base/src/main/java/org/alfresco/transform/base/probes/ProbeTransform.java @@ -256,7 +256,7 @@ public class ProbeTransform private File getSourceFile(boolean isLiveProbe) { incrementTransformerCount(); - File sourceFile = createTempFile("source_", "_" + sourceFilename); + File sourceFile = createTempFile("probe_source_", "_" + sourceFilename); try (InputStream inputStream = getClass().getResourceAsStream('/' + sourceFilename)) { Files.copy(inputStream, sourceFile.toPath(), StandardCopyOption.REPLACE_EXISTING); @@ -273,7 +273,7 @@ public class ProbeTransform private File getTargetFile() { - File targetFile = createTempFile("target_", "_" + sourceFilename); + File targetFile = createTempFile("probe_target_", "_" + sourceFilename); LogEntry.setTarget(targetFile.getName()); return targetFile; } 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 8d334760..ad4b4e67 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 @@ -31,10 +31,8 @@ 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; @@ -45,7 +43,6 @@ 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; @@ -64,7 +61,6 @@ import java.util.UUID; 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; @@ -73,12 +69,9 @@ 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; /** @@ -301,8 +294,6 @@ public abstract class AbstractBaseTest { mockMvc.perform( mockMvcRequest(ENDPOINT_TRANSFORM, sourceFile)) - .andExpect(request().asyncStarted()) - .andDo(MvcResult::getAsyncResult) .andExpect(status().isOk()) .andExpect(content().bytes(expectedTargetFileBytes)) .andExpect(header().string("Content-Disposition", @@ -324,8 +315,6 @@ public abstract class AbstractBaseTest mockMvc.perform( mockMvcRequest(ENDPOINT_TRANSFORM, sourceFile)) - .andExpect(request().asyncStarted()) - .andDo(MvcResult::getAsyncResult) .andExpect(status().isOk()) .andExpect(content().bytes(expectedTargetFileBytes)) .andExpect(header().string("Content-Disposition", @@ -339,8 +328,6 @@ public abstract class AbstractBaseTest mockMvc.perform( mockMvcRequest(ENDPOINT_TRANSFORM, sourceFile)) - .andExpect(request().asyncStarted()) - .andDo(MvcResult::getAsyncResult) .andExpect(status().isOk()) .andExpect(content().bytes(expectedTargetFileBytes)) .andExpect(header().string("Content-Disposition", @@ -445,13 +432,9 @@ public abstract class AbstractBaseTest File dauSourceFile = getTestFile("quick." + sourceExtension, true); String directUrl = "file://" + dauSourceFile.toPath(); - MvcResult mvcResult = mockMvc.perform( + ResultActions resultActions = 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)); 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 d860b191..eaef5ac6 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 @@ -205,17 +205,13 @@ public class TransformControllerAllInOneTest @Test public void testTransformEndpointUsingTransformEngineWithTwoCustomTransformers() throws Exception { - MvcResult mvcResult = mockMvc.perform( + mockMvc.perform( MockMvcRequestBuilders.multipart(ENDPOINT_TRANSFORM) .file(new MockMultipartFile("file", null, MIMETYPE_TEXT_PLAIN, "Start".getBytes(StandardCharsets.UTF_8))) .param(SOURCE_MIMETYPE, MIMETYPE_TEXT_PLAIN) .param(TARGET_MIMETYPE, MIMETYPE_PDF) .param(PAGE_REQUEST_PARAM, "1")) - .andExpect(request().asyncStarted()) - .andReturn(); - - mockMvc.perform(asyncDispatch(mvcResult)) .andExpect(status().isOk()) .andExpect(header().string("Content-Disposition", "attachment; filename*=UTF-8''transform.pdf")) @@ -225,19 +221,15 @@ public class TransformControllerAllInOneTest @Test public void testTransformEndpointUsingTransformEngineWithOneCustomTransformer() throws Exception { - MvcResult mvcResult = mockMvc.perform( + mockMvc.perform( MockMvcRequestBuilders.multipart(ENDPOINT_TRANSFORM) .file(new MockMultipartFile("file", null, MIMETYPE_PDF, "Start".getBytes(StandardCharsets.UTF_8))) .param(SOURCE_MIMETYPE, MIMETYPE_PDF) .param(TARGET_MIMETYPE, MIMETYPE_IMAGE_JPEG)) - .andExpect(request().asyncStarted()) - .andReturn(); - - mockMvc.perform(asyncDispatch(mvcResult)) - .andExpect(status().isOk()) - .andExpect(header().string("Content-Disposition", - "attachment; filename*=UTF-8''transform.jpeg")) - .andExpect(content().string("Start -> Pdf2Jpg()")); + .andExpect(status().isOk()) + .andExpect(header().string("Content-Disposition", + "attachment; filename*=UTF-8''transform.jpeg")) + .andExpect(content().string("Start -> Pdf2Jpg()")); } } 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 83c50e75..36cdd365 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 @@ -58,7 +58,6 @@ 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; @@ -100,10 +99,8 @@ 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; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** @@ -336,17 +333,13 @@ public class TransformControllerTest @Test public void testTransformEndpointThatUploadsAndDownloadsContent() throws Exception { - MvcResult mvcResult = mockMvc.perform( + mockMvc.perform( MockMvcRequestBuilders.multipart(ENDPOINT_TRANSFORM) .file(new MockMultipartFile("file", null, MIMETYPE_TEXT_PLAIN, "Start".getBytes(StandardCharsets.UTF_8))) .param(SOURCE_MIMETYPE, MIMETYPE_TEXT_PLAIN) .param(TARGET_MIMETYPE, MIMETYPE_PDF) .param(PAGE_REQUEST_PARAM, "1")) - .andExpect(request().asyncStarted()) - .andReturn(); - - mockMvc.perform(asyncDispatch(mvcResult)) .andExpect(status().isOk()) .andExpect(header().string("Content-Disposition", "attachment; filename*=UTF-8''transform.pdf")) @@ -362,7 +355,7 @@ public class TransformControllerTest TransformHandler spy = spy(orig); transformController.transformHandler = spy; - MvcResult mvcResult = mockMvc.perform( + mockMvc.perform( MockMvcRequestBuilders.multipart(ENDPOINT_TEST) .file(new MockMultipartFile("file", null, MIMETYPE_TEXT_PLAIN, "Start".getBytes(StandardCharsets.UTF_8))) @@ -373,12 +366,10 @@ public class TransformControllerTest .param(PAGE_REQUEST_PARAM, "replaced") .param("name1", "hasNoValueSoRemoved").param("value1", "") .param("name2", PAGE_REQUEST_PARAM).param("value2", "1") - .param("name3", SOURCE_ENCODING).param("value3", "UTF-8")) - .andExpect(request().asyncStarted()) - .andReturn(); + .param("name3", SOURCE_ENCODING).param("value3", "UTF-8")); // Do the dispatch, just in case not doing it leaves it in a strange state. - mockMvc.perform(asyncDispatch(mvcResult)); +// mockMvc.perform(asyncDispatch(mvcResult)); verify(spy).handleHttpRequest(any(), any(), eq(MIMETYPE_TEXT_PLAIN), eq(MIMETYPE_PDF), eq(ImmutableMap.of( @@ -407,17 +398,13 @@ public class TransformControllerTest @Test public void testInterceptOfTransformException_noTransformers() throws Exception { - MvcResult mvcResult = mockMvc.perform( + mockMvc.perform( MockMvcRequestBuilders.multipart(ENDPOINT_TRANSFORM) .file(new MockMultipartFile("file", null, MIMETYPE_TEXT_PLAIN, "Start".getBytes(StandardCharsets.UTF_8))) .param(SOURCE_MIMETYPE, MIMETYPE_TEXT_PLAIN) .param(TARGET_MIMETYPE, MIMETYPE_PDF) .param("unknown", "1")) - .andExpect(request().asyncStarted()) - .andReturn(); - - mockMvc.perform(asyncDispatch(mvcResult)) .andExpect(status().isBadRequest()) .andExpect(content().string(containsString("TwoCustomTransformers Error Page"))) .andExpect(content().string(containsString("No transforms were able to handle the request"))); 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 index cda388f4..e2f184ba 100644 --- a/engines/base/src/test/java/org/alfresco/transform/base/TransformStreamHandlerTest.java +++ b/engines/base/src/test/java/org/alfresco/transform/base/TransformStreamHandlerTest.java @@ -430,10 +430,20 @@ public class TransformStreamHandlerTest @Test public void testSimulatedHandleHttpRequest() throws Exception { + File targetFile = tempFile(); + try (ByteArrayOutputStream os = new ByteArrayOutputStream()) { new FakeTransformStreamHandler() { + @Override + protected void init() throws IOException + { + transformManager.setTargetFile(targetFile); + transformManager.keepTargetFile(); + super.init(); + } + @Override protected InputStream getInputStream() { @@ -525,4 +535,31 @@ public class TransformStreamHandlerTest } }.handleTransformRequest(); } + + @Test + // Tried and failed to create TransformHandler.handleHttpRequest(...) that returned a + // ResponseEntity (and other async variants) so that we would not need a temporary target + // file as a StreamingResponseBody would have allowed us to write directly to the OutputStream. However, I was + // unable to find a way to defer setting the httpStatus in the response until we knew there were no Exceptions + // thrown in processing. Keeping the following test (it does no harm) to show how much simpler it would have been. + public void testSimulatedHandleHttpRequestWithStreamingResponseBody() throws Exception + { + try (ByteArrayOutputStream os = new ByteArrayOutputStream()) + { + new FakeTransformStreamHandler() + { + @Override + protected InputStream getInputStream() + { + return getSourceInputStreamFromBytes(); + } + + @Override + protected OutputStream getOutputStream() + { + return os; + } + }.handleTransformRequest(); + } + } } 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 6a8fcc7e..e4ca697d 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 @@ -216,8 +216,6 @@ public class ImageMagickTest extends AbstractBaseTest .param("targetMimetype", targetMimetype) .param("sourceMimetype", sourceMimetype) .param("cropGravity", value)) - .andExpect(request().asyncStarted()) - .andDo(MvcResult::getAsyncResult) .andExpect(status().isOk()) .andExpect(content().bytes(expectedTargetFileBytes)) .andExpect(header().string("Content-Disposition", @@ -270,8 +268,6 @@ public class ImageMagickTest extends AbstractBaseTest .param("resizePercentage", "true") .param("allowEnlargement", "true") .param("maintainAspectRatio", "false")) - .andExpect(request().asyncStarted()) - .andDo(MvcResult::getAsyncResult) .andExpect(status().isOk()) .andExpect(content().bytes(expectedTargetFileBytes)) .andExpect(header().string("Content-Disposition", @@ -310,8 +306,6 @@ public class ImageMagickTest extends AbstractBaseTest .param("resizePercentage", "false") .param("allowEnlargement", "false") .param("maintainAspectRatio", "true")) - .andExpect(request().asyncStarted()) - .andDo(MvcResult::getAsyncResult) .andExpect(status().isOk()) .andExpect(content().bytes(expectedTargetFileBytes)) .andExpect(header().string("Content-Disposition", @@ -334,8 +328,6 @@ public class ImageMagickTest extends AbstractBaseTest .param("resizeWidth", "321") .param("resizeHeight", "654") .param("commandOptions", "( horrible command / );")) - .andExpect(request().asyncStarted()) - .andDo(MvcResult::getAsyncResult) .andExpect(status().isOk()) .andExpect(content().bytes(expectedTargetFileBytes)) .andExpect(header().string("Content-Disposition", 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 d09f7625..929fd705 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 @@ -55,9 +55,7 @@ import static org.alfresco.transform.common.RequestParamMap.TARGET_MIMETYPE; 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.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch; 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; /** @@ -499,11 +497,7 @@ public class MiscTest extends AbstractBaseTest requestBuilder.param("extractMapping", extractMapping); } - MvcResult mvcResult = mockMvc.perform(requestBuilder) - .andExpect(request().asyncStarted()) - .andReturn(); - - return mockMvc.perform(asyncDispatch(mvcResult)) + return mockMvc.perform(requestBuilder) .andExpect(status().isOk()) .andExpect(header().string("Content-Disposition", "attachment; filename*=" + 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 a3e1af8f..5695202d 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 @@ -214,8 +214,6 @@ public class PdfRendererTest extends AbstractBaseTest .param("height", "654") .param("allowPdfEnlargement", "true") .param("maintainPdfAspectRatio", "true")) - .andExpect(request().asyncStarted()) - .andDo(MvcResult::getAsyncResult) .andExpect(status().isOk()) .andExpect(content().bytes(expectedTargetFileBytes)) .andExpect(header().string("Content-Disposition", @@ -240,8 +238,6 @@ public class PdfRendererTest extends AbstractBaseTest .param("height", "654") .param("allowPdfEnlargement", "false") .param("maintainPdfAspectRatio", "false")) - .andExpect(request().asyncStarted()) - .andDo(MvcResult::getAsyncResult) .andExpect(status().isOk()) .andExpect(content().bytes(expectedTargetFileBytes)) .andExpect(header().string("Content-Disposition", 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 b31b441f..8ab00707 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 @@ -45,7 +45,6 @@ import org.springframework.mock.web.MockMultipartFile; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import javax.servlet.http.HttpServletRequest; import java.io.ByteArrayInputStream; @@ -86,12 +85,10 @@ import static org.alfresco.transform.tika.transformers.Tika.TEXT_MINING; import static org.alfresco.transform.tika.transformers.Tika.TIKA_AUTO; import static org.alfresco.transform.tika.transformers.Tika.TXT; import static org.alfresco.transform.tika.transformers.Tika.XHTML; -import static org.alfresco.transform.tika.transformers.Tika.XML; import static org.alfresco.transform.tika.transformers.Tika.XLSX; +import static org.alfresco.transform.tika.transformers.Tika.XML; import static org.alfresco.transform.tika.transformers.Tika.ZIP; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; 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; @@ -104,8 +101,8 @@ import static org.springframework.http.HttpStatus.OK; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.http.MediaType.APPLICATION_PDF_VALUE; import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** * Test Tika. @@ -175,15 +172,11 @@ public class TikaTest extends AbstractBaseTest "targetExtension", this.targetExtension) : mockMvcRequest(ENDPOINT_TRANSFORM, sourceFile, "targetExtension", this.targetExtension, INCLUDE_CONTENTS, includeContents.toString()); - MvcResult mvcResult = mockMvc.perform(requestBuilder) - .andExpect(request().asyncStarted()) - .andReturn(); - - MvcResult result = mockMvc.perform(asyncDispatch(mvcResult)) - .andExpect(MockMvcResultMatchers.status().is(OK.value())) - .andExpect(MockMvcResultMatchers.header().string("Content-Disposition", - "attachment; filename*=UTF-8''transform." + this.targetExtension)). - andReturn(); + MvcResult result = mockMvc.perform(requestBuilder) + .andExpect(status().is(OK.value())) + .andExpect(header().string("Content-Disposition", + "attachment; filename*=UTF-8''transform." + this.targetExtension)) + .andReturn(); String content = result.getResponse().getContentAsString(); assertTrue(content.contains(expectedContentContains), "The content did not include \"" + expectedContentContains); @@ -256,13 +249,9 @@ public class TikaTest extends AbstractBaseTest // mockMvcRequest(ENDPOINT_TRANSFORM, sourceFile, "targetExtension", targetExtension)) // .andExpect(MockMvcResultMatchers.status().is(INTERNAL_SERVER_ERROR.value())); - MvcResult mvcResult = mockMvc.perform( + mockMvc.perform( mockMvcRequest(ENDPOINT_TRANSFORM, sourceFile, "targetExtension", targetExtension)) - .andExpect(request().asyncStarted()) - .andReturn(); - - mockMvc.perform(asyncDispatch(mvcResult)) - .andExpect(MockMvcResultMatchers.status().is(INTERNAL_SERVER_ERROR.value())); + .andExpect(status().is(INTERNAL_SERVER_ERROR.value())); } // --- Archive --- @@ -452,13 +441,9 @@ public class TikaTest extends AbstractBaseTest "targetMimetype", MIMETYPE_METADATA_EMBED, "sourceMimetype", MIMETYPE_OPENXML_SPREADSHEET); - MvcResult mvcResult = mockMvc.perform(requestBuilder) - .andExpect(request().asyncStarted()) - .andReturn(); - - MvcResult result = mockMvc.perform(asyncDispatch(mvcResult)) - .andExpect(MockMvcResultMatchers.status().is(OK.value())) - .andExpect(MockMvcResultMatchers.header().string("Content-Disposition", + MvcResult result = mockMvc.perform(requestBuilder) + .andExpect(status().is(OK.value())) + .andExpect(header().string("Content-Disposition", "attachment; filename*=UTF-8''transform." + targetExtension)). andReturn(); @@ -482,8 +467,8 @@ public class TikaTest extends AbstractBaseTest mockMvc.perform( mockMvcRequest(ENDPOINT_TRANSFORM, sourceFile, "targetExtension", targetExtension).param( NOT_EXTRACT_BOOKMARKS_TEXT, "true")) - .andExpect(MockMvcResultMatchers.status().is(OK.value())) - .andExpect(MockMvcResultMatchers.header().string("Content-Disposition", + .andExpect(status().is(OK.value())) + .andExpect(header().string("Content-Disposition", "attachment; filename*=UTF-8''transform." + targetExtension)); } @@ -529,7 +514,7 @@ public class TikaTest extends AbstractBaseTest .header(ACCEPT, APPLICATION_JSON_VALUE) .header(CONTENT_TYPE, APPLICATION_JSON_VALUE) .content(tr)) - .andExpect(MockMvcResultMatchers.status().is(CREATED.value())) + .andExpect(status().is(CREATED.value())) .andReturn().getResponse().getContentAsString(); TransformReply transformReply = objectMapper.readValue(transformationReplyAsString,