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
This commit is contained in:
alandavis
2022-07-25 11:44:51 +01:00
parent e837feb559
commit e982486d33
40 changed files with 1330 additions and 809 deletions

View File

@@ -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<String, String> 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));
}
}
}

View File

@@ -53,6 +53,12 @@
<dependency>
<groupId>org.alfresco</groupId>
<artifactId>alfresco-jodconverter-core</artifactId>
<exclusions>
<exclusion>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>

View File

@@ -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
{
}

View File

@@ -53,6 +53,7 @@ public class AIOQueueTest extends AbstractQueueTest
.withClientData("ACS")
.withSourceReference(UUID.randomUUID().toString())
.withSourceSize(32L)
.withInternalContextForTransformEngineTests()
.build();
}
}

View File

@@ -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

View File

@@ -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<TransformReply> 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<StreamingResponseBody> 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<StreamingResponseBody> testTransform(HttpServletRequest request,
@RequestParam(value = FILE, required = false) MultipartFile sourceMultipartFile,

View File

@@ -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<String> 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<TransformEngine> transformEngines;
@Autowired(required = false)
private List<CustomTransformer> 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<String, String> transformOptions;
protected String reference;
TransformProcess(String sourceMimetype, String targetMimetype, Map<String, String> 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<String, String> 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<StreamingResponseBody> 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<String, String> 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)
{
new TransformProcess(request.getSourceMediaType(), request.getTargetMediaType(),
request.getTransformRequestOptions(), "unset")
public TransformReply handleMessageRequest(TransformRequest request, Long timeout, Destination replyToQueue)
{
TransformReply reply = createBasicTransformReply(request);
new TransformProcess(this, request.getSourceMediaType(), request.getTargetMediaType(),
request.getTransformRequestOptions(), "unset")
{
@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<String, String> 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<String, String> cleanTransformOptions(Map<String, String> requestParameters)
public Map<String, String> cleanTransformOptions(Map<String, String> requestParameters)
{
Map<String, String> transformOptions = new HashMap<>(requestParameters);
transformOptions.keySet().removeAll(NON_TRANSFORM_OPTION_REQUEST_PARAMETERS);
@@ -539,19 +413,19 @@ public class TransformHandler
}
private InputStream getInputStreamForHandleHttpRequest(Map<String, String> 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<String, String> transformOptions)
public String getTransformerName(final String sourceMimetype, long sourceSizeInBytes, final String targetMimetype,
final Map<String, String> 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<StreamingResponseBody> createResponseEntity(String targetMimetype,
StreamingResponseBody body)
{

View File

@@ -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)
{
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;
}
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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<String, String> transformOptions;
protected String reference;
TransformProcess(TransformHandler transformHandler, String sourceMimetype, String targetMimetype,
Map<String, String> 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);
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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();
}
}

View File

@@ -58,18 +58,18 @@ public class TransformReplySender
public void send(final Destination destination, final TransformReply reply, final String correlationId)
{
try
if (destination != null)
{
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)
{
} catch (Exception e) {
logger.error("Failed to send T-Reply " + reply + " - for correlation ID " + correlationId, e);
}
}
}
}

View File

@@ -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;
}
}

View File

@@ -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<TransformOption> transformOptionGroup = ImmutableSet.of(
new TransformOptionValue(false, "cropGravity"));
Set<TransformOption> transformOptions = ImmutableSet.of(
new TransformOptionValue(false, "page"),
new TransformOptionValue(false, "width"),
new TransformOptionGroup(false, transformOptionGroup));
Map<String, Set<TransformOption>> transformOptionsMap = ImmutableMap.of("engineXOptions",
transformOptions);
Transformer transformer = buildTransformer("application/pdf", "image/png", "engineXOptions",
"engineX");
List<Transformer> 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<SupportedSourceAndTarget> 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(
MvcResult mvcResult = mockMvc.perform(
mockMvcRequest(ENDPOINT_TRANSFORM, null)
.param("targetExtension", targetExtension)
.param(DIRECT_ACCESS_URL, directUrl))
.andExpect(status().is(OK.value()));
.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)
{

View File

@@ -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);

View File

@@ -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;

View File

@@ -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());

View File

@@ -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<String,File> 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

View File

@@ -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<String, String> 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));
// }
// }
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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();
}
}

View File

@@ -53,6 +53,7 @@ public class ImageMagickQueueTest extends AbstractQueueTest
.withClientData("ACS")
.withSourceReference(UUID.randomUUID().toString())
.withSourceSize(32L)
.withInternalContextForTransformEngineTests()
.build();
}
}

View File

@@ -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,

View File

@@ -52,6 +52,7 @@ public class LibreOfficeQueueTest extends AbstractQueueTest
.withClientData("ACS")
.withSourceReference(UUID.randomUUID().toString())
.withSourceSize(32L)
.withInternalContextForTransformEngineTests()
.build();
}
}

View File

@@ -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)

View File

@@ -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);

View File

@@ -48,6 +48,8 @@ public class MiscQueueTest extends AbstractQueueTest
.withSchema(1)
.withClientData("ACS")
.withSourceReference(UUID.randomUUID().toString())
.withSourceSize(32L).build();
.withSourceSize(32L)
.withInternalContextForTransformEngineTests()
.build();
}
}

View File

@@ -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)

View File

@@ -52,6 +52,8 @@ public class PdfRendererQueueTest extends AbstractQueueTest
.withSchema(1)
.withClientData("ACS")
.withSourceReference(UUID.randomUUID().toString())
.withSourceSize(32L).build();
.withSourceSize(32L)
.withInternalContextForTransformEngineTests()
.build();
}
}

View File

@@ -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,

View File

@@ -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<String, FileInfo> TEST_FILES = Stream.of(

View File

@@ -52,6 +52,8 @@ public class TikaQueueTest extends AbstractQueueTest
.withSchema(1)
.withClientData("ACS")
.withSourceReference(UUID.randomUUID().toString())
.withSourceSize(32L).build();
.withSourceSize(32L)
.withInternalContextForTransformEngineTests()
.build();
}
}

View File

@@ -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<RuntimeExec.ExecutionResult>) invocation -> {
Map<String, String> 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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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());
}
}

View File

@@ -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";

View File

@@ -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()