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); transformer.setSupportedSourceAndTargetList(supportedSourceAndTargetList);
return transformer; 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> <dependency>
<groupId>org.alfresco</groupId> <groupId>org.alfresco</groupId>
<artifactId>alfresco-jodconverter-core</artifactId> <artifactId>alfresco-jodconverter-core</artifactId>
<exclusions>
<exclusion>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.pdfbox</groupId> <groupId>org.apache.pdfbox</groupId>

View File

@@ -26,8 +26,8 @@
*/ */
package org.alfresco.transform.aio; 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") .withClientData("ACS")
.withSourceReference(UUID.randomUUID().toString()) .withSourceReference(UUID.randomUUID().toString())
.withSourceSize(32L) .withSourceSize(32L)
.withInternalContextForTransformEngineTests()
.build(); .build();
} }
} }

View File

@@ -30,6 +30,7 @@ import org.alfresco.transform.base.AbstractBaseTest;
import org.alfresco.transform.client.model.TransformRequest; import org.alfresco.transform.client.model.TransformRequest;
import org.alfresco.transform.config.TransformConfig; import org.alfresco.transform.config.TransformConfig;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@@ -51,13 +52,13 @@ public class AIOTest extends AbstractBaseTest
//@Override //@Override
protected void mockTransformCommand(String sourceExtension, String targetExtension, String sourceMimetype, protected void mockTransformCommand(String sourceExtension, String targetExtension, String sourceMimetype,
boolean readTargetFileBytes) throws IOException { boolean readTargetFileBytes) throws IOException
// TODO Auto-generated method stub {
} }
//@Override //@Override
protected void updateTransformRequestWithSpecificOptions(TransformRequest transformRequest) { protected void updateTransformRequestWithSpecificOptions(TransformRequest transformRequest)
// TODO Auto-generated method stub {
} }
@Test @Test

View File

@@ -28,6 +28,8 @@ package org.alfresco.transform.base;
import org.alfresco.transform.base.logging.LogEntry; import org.alfresco.transform.base.logging.LogEntry;
import org.alfresco.transform.base.probes.ProbeTransform; 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.common.TransformException;
import org.alfresco.transform.config.TransformConfig; import org.alfresco.transform.config.TransformConfig;
import org.alfresco.transform.registry.TransformServiceRegistry; 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.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; 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.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; 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.alfresco.transform.config.CoreVersionDecorator.setOrClearCoreVersion;
import static org.springframework.http.HttpStatus.BAD_REQUEST; import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.OK; 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; import static org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE;
/** /**
@@ -106,7 +110,7 @@ public class TransformController
private void init() private void init()
{ {
transformEngine = transformHandler.getTransformEngine(); transformEngine = transformHandler.getTransformEngine();
probeTransform = transformHandler.getProbeTestTransform(); probeTransform = transformHandler.getProbeTransform();
} }
@EventListener(ApplicationReadyEvent.class) @EventListener(ApplicationReadyEvent.class)
@@ -205,6 +209,18 @@ public class TransformController
return new ResponseEntity<>(transformConfig, OK); 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) @PostMapping(value = ENDPOINT_TRANSFORM, consumes = MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<StreamingResponseBody> transform(HttpServletRequest request, public ResponseEntity<StreamingResponseBody> transform(HttpServletRequest request,
@RequestParam(value = FILE, required = false) MultipartFile sourceMultipartFile, @RequestParam(value = FILE, required = false) MultipartFile sourceMultipartFile,
@@ -216,6 +232,7 @@ public class TransformController
targetMimetype, requestParameters); targetMimetype, requestParameters);
} }
// Used the t-engine's simple html test UI.
@PostMapping(value = ENDPOINT_TEST, consumes = MULTIPART_FORM_DATA_VALUE) @PostMapping(value = ENDPOINT_TEST, consumes = MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<StreamingResponseBody> testTransform(HttpServletRequest request, public ResponseEntity<StreamingResponseBody> testTransform(HttpServletRequest request,
@RequestParam(value = FILE, required = false) MultipartFile sourceMultipartFile, @RequestParam(value = FILE, required = false) MultipartFile sourceMultipartFile,

View File

@@ -27,7 +27,6 @@
package org.alfresco.transform.base; package org.alfresco.transform.base;
import org.alfresco.transform.base.clients.AlfrescoSharedFileStoreClient; 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.messaging.TransformReplySender;
import org.alfresco.transform.base.model.FileRefResponse; import org.alfresco.transform.base.model.FileRefResponse;
import org.alfresco.transform.base.probes.ProbeTransform; 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_ENCODING;
import static org.alfresco.transform.common.RequestParamMap.SOURCE_EXTENSION; 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.SOURCE_MIMETYPE;
import static org.alfresco.transform.common.RequestParamMap.TARGET_EXTENSION;
import static org.alfresco.transform.common.RequestParamMap.TARGET_MIMETYPE; import static org.alfresco.transform.common.RequestParamMap.TARGET_MIMETYPE;
import static org.springframework.http.HttpStatus.BAD_REQUEST; import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.CREATED; import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; 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. * Handles the transform requests from either http or a message.
@@ -97,15 +96,14 @@ import static org.springframework.http.HttpStatus.OK;
public class TransformHandler public class TransformHandler
{ {
private static final Logger logger = LoggerFactory.getLogger(TransformHandler.class); private static final Logger logger = LoggerFactory.getLogger(TransformHandler.class);
private static final List<String> NON_TRANSFORM_OPTION_REQUEST_PARAMETERS = Arrays.asList(SOURCE_EXTENSION, 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) @Autowired(required = false)
private List<TransformEngine> transformEngines; private List<TransformEngine> transformEngines;
@Autowired(required = false) @Autowired(required = false)
private List<CustomTransformer> customTransformers; private List<CustomTransformer> customTransformers;
@Autowired @Autowired
private AlfrescoSharedFileStoreClient alfrescoSharedFileStoreClient; private AlfrescoSharedFileStoreClient alfrescoSharedFileStoreClient;
@Autowired @Autowired
@@ -177,121 +175,14 @@ public class TransformHandler
return transformEngine; return transformEngine;
} }
public ProbeTransform getProbeTestTransform() public ProbeTransform getProbeTransform()
{ {
return probeTransform; return probeTransform;
} }
private abstract class TransformProcess public TransformerDebug getTransformerDebug()
{ {
protected final String sourceMimetype; return transformerDebug;
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);
}
} }
public ResponseEntity<StreamingResponseBody> handleHttpRequest(HttpServletRequest request, public ResponseEntity<StreamingResponseBody> handleHttpRequest(HttpServletRequest request,
@@ -300,19 +191,20 @@ public class TransformHandler
{ {
return createResponseEntity(targetMimetype, os -> return createResponseEntity(targetMimetype, os ->
{ {
new TransformProcess(sourceMimetype, targetMimetype, requestParameters, new TransformProcess(this, sourceMimetype, targetMimetype, requestParameters,
"e" + httpRequestCount.getAndIncrement()) "e" + httpRequestCount.getAndIncrement())
{ {
@Override @Override
protected void init(TransformManagerImpl transformManager) protected void init() throws IOException
{ {
transformManager.setRequest(request); transformManager.setRequest(request);
super.init();
} }
@Override @Override
protected InputStream getInputStream(TransformManagerImpl transformManager) protected InputStream getInputStream()
{ {
return getInputStreamForHandleHttpRequest(requestParameters, sourceMultipartFile, transformManager); return getInputStreamForHandleHttpRequest(requestParameters, sourceMultipartFile);
} }
@Override @Override
@@ -322,13 +214,13 @@ public class TransformHandler
} }
@Override @Override
protected OutputStream getOutputStream(TransformManagerImpl transformManager) protected OutputStream getOutputStream()
{ {
return transformManager.setOutputStream(os); return transformManager.setOutputStream(os);
} }
@Override @Override
protected void closeOutputStream(TransformManagerImpl transformManager) throws IOException protected void closeOutputStream() throws IOException
{ {
// Do nothing as the Spring mvc handles this for HttpServletRequest // 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, public void handleProbRequest(String sourceMimetype, String targetMimetype, Map<String, String> transformOptions,
File sourceFile, File targetFile) File sourceFile, File targetFile)
{ {
new TransformProcess(sourceMimetype, targetMimetype, transformOptions, new TransformProcess(this, sourceMimetype, targetMimetype, transformOptions,
"p" + httpRequestCount.getAndIncrement()) "p" + httpRequestCount.getAndIncrement())
{ {
@Override @Override
protected void init(TransformManagerImpl transformManager) protected void init() throws IOException
{ {
transformManager.setSourceFile(sourceFile); transformManager.setSourceFile(sourceFile);
transformManager.setTargetFile(targetFile); transformManager.setTargetFile(targetFile);
transformManager.setSourceFileCreated(); transformManager.keepTargetFile();
// We don't want to delete the target file, so don't call setTargetFileCreated() super.init();
} }
@Override @Override
protected InputStream getInputStream(TransformManagerImpl transformManager) protected InputStream getInputStream()
{ {
return getInputStreamForHandleProbRequest(sourceFile, transformManager); return getInputStreamForHandleProbRequest(sourceFile);
} }
@Override @Override
@@ -364,39 +256,31 @@ public class TransformHandler
} }
@Override @Override
protected OutputStream getOutputStream(TransformManagerImpl transformManager) protected OutputStream getOutputStream() throws IOException
throws FileNotFoundException
{ {
return getOutputStreamFromFile(targetFile, transformManager); return getOutputStreamFromFile(targetFile);
} }
}.handleTransformRequest(); }.handleTransformRequest();
} }
public void handleMessageRequest(TransformRequest request, Long timeout, Destination replyToQueue) public TransformReply handleMessageRequest(TransformRequest request, Long timeout, Destination replyToQueue)
{
new TransformProcess(request.getSourceMediaType(), request.getTargetMediaType(),
request.getTransformRequestOptions(), "unset")
{ {
TransformReply reply = createBasicTransformReply(request); TransformReply reply = createBasicTransformReply(request);
new TransformProcess(this, request.getSourceMediaType(), request.getTargetMediaType(),
request.getTransformRequestOptions(), "unset")
{
@Override @Override
protected void init(TransformManagerImpl transformManager) protected void init() throws IOException
{ {
checkTransformRequestValid(request, reply); checkTransformRequestValid(request, reply);
reference = TransformStack.getReference(reply.getInternalContext()); reference = TransformStack.getReference(reply.getInternalContext());
super.init();
} }
@Override @Override
protected InputStream getInputStream(TransformManagerImpl transformManager) protected InputStream getInputStream()
{ {
return getInputStreamForHandleMessageRequest(request, transformManager); return getInputStreamForHandleMessageRequest(request);
}
@Override
protected void transformerDebugPushTransform(long sourceSizeInBytes, Map<String, String> transformOptions, String transformName)
{
transformerDebug.pushTransform(request);
transformerDebug.logOptions(request);
} }
@Override @Override
@@ -406,12 +290,10 @@ public class TransformHandler
} }
@Override @Override
protected OutputStream getOutputStream(TransformManagerImpl transformManager) protected OutputStream getOutputStream() throws IOException
throws FileNotFoundException
{ {
File targetFile = transformManager.setTargetFile(createTargetFile(null, sourceMimetype, targetMimetype)); File targetFile = transformManager.setTargetFile(createTargetFile(null, sourceMimetype, targetMimetype));
transformManager.setTargetFileCreated(); return getOutputStreamFromFile(targetFile);
return getOutputStreamFromFile(targetFile, transformManager);
} }
protected void sendTransformResponse(TransformManagerImpl transformManager) protected void sendTransformResponse(TransformManagerImpl transformManager)
@@ -428,11 +310,12 @@ public class TransformHandler
} }
@Override @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(); }.handleTransformRequest();
return reply;
} }
private void sendSuccessfulResponse(Long timeout, TransformReply reply, Destination replyToQueue) private void sendSuccessfulResponse(Long timeout, TransformReply reply, Destination replyToQueue)
@@ -451,15 +334,6 @@ public class TransformHandler
transformReplySender.send(replyToQueue, reply); transformReplySender.send(replyToQueue, reply);
} }
private void deleteTmpFiles(TransformManagerImpl transformManager)
{
if (transformManager != null)
{
transformManager.deleteSourceFileIfCreated();
transformManager.deleteTargetFileIfCreated();
}
}
private void checkTransformRequestValid(TransformRequest request, TransformReply reply) private void checkTransformRequestValid(TransformRequest request, TransformReply reply)
{ {
final Errors errors = validateTransformRequest(request); final Errors errors = validateTransformRequest(request);
@@ -507,7 +381,7 @@ public class TransformHandler
request.setInternalContext(InternalContext.initialise(request.getInternalContext())); 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); Map<String, String> transformOptions = new HashMap<>(requestParameters);
transformOptions.keySet().removeAll(NON_TRANSFORM_OPTION_REQUEST_PARAMETERS); transformOptions.keySet().removeAll(NON_TRANSFORM_OPTION_REQUEST_PARAMETERS);
@@ -539,19 +413,19 @@ public class TransformHandler
} }
private InputStream getInputStreamForHandleHttpRequest(Map<String, String> requestParameters, private InputStream getInputStreamForHandleHttpRequest(Map<String, String> requestParameters,
MultipartFile sourceMultipartFile, TransformManagerImpl transformManager) MultipartFile sourceMultipartFile)
{ {
final String directUrl = requestParameters.getOrDefault(DIRECT_ACCESS_URL, ""); final String directUrl = requestParameters.getOrDefault(DIRECT_ACCESS_URL, "");
return transformManager.setInputStream(new BufferedInputStream(directUrl.isBlank() ? return new BufferedInputStream(directUrl.isBlank()
getMultipartFileInputStream(sourceMultipartFile) : ? getMultipartFileInputStream(sourceMultipartFile)
getDirectAccessUrlInputStream(directUrl))); : getDirectAccessUrlInputStream(directUrl));
} }
private InputStream getInputStreamForHandleProbRequest(File sourceFile, TransformManagerImpl transformManager) private InputStream getInputStreamForHandleProbRequest(File sourceFile)
{ {
try try
{ {
return transformManager.setInputStream(new BufferedInputStream(new FileInputStream(sourceFile))); return new BufferedInputStream(new FileInputStream(sourceFile));
} }
catch (FileNotFoundException e) catch (FileNotFoundException e)
{ {
@@ -559,15 +433,14 @@ public class TransformHandler
} }
} }
private InputStream getInputStreamForHandleMessageRequest(TransformRequest request, private InputStream getInputStreamForHandleMessageRequest(TransformRequest request)
TransformManagerImpl transformManager)
{ {
final String directUrl = request.getTransformRequestOptions().getOrDefault(DIRECT_ACCESS_URL, ""); final String directUrl = request.getTransformRequestOptions().getOrDefault(DIRECT_ACCESS_URL, "");
try try
{ {
return transformManager.setInputStream(new BufferedInputStream(directUrl.isBlank() return new BufferedInputStream(directUrl.isBlank()
? getSharedFileStoreInputStream(request.getSourceReference()) ? getSharedFileStoreInputStream(request.getSourceReference())
: getDirectAccessUrlInputStream(directUrl))); : getDirectAccessUrlInputStream(directUrl));
} }
catch (TransformException e) catch (TransformException e)
{ {
@@ -579,10 +452,9 @@ public class TransformHandler
} }
} }
private OutputStream getOutputStreamFromFile(File targetFile, TransformManagerImpl transformManager) private OutputStream getOutputStreamFromFile(File targetFile) throws IOException
throws FileNotFoundException
{ {
return transformManager.setOutputStream(new BufferedOutputStream(new FileOutputStream(targetFile))); return new BufferedOutputStream(new FileOutputStream(targetFile));
} }
private void saveTargetFileInSharedFileStore(File targetFile, TransformReply reply) private void saveTargetFileInSharedFileStore(File targetFile, TransformReply reply)
@@ -627,8 +499,8 @@ public class TransformHandler
return sb.toString(); return sb.toString();
} }
private String getTransformerName(long sourceSizeInBytes, final String sourceMimetype, public String getTransformerName(final String sourceMimetype, long sourceSizeInBytes, final String targetMimetype,
final String targetMimetype, final Map<String, String> transformOptions) final Map<String, String> transformOptions)
{ {
// The transformOptions always contains sourceEncoding when sent to a T-Engine, even though it should not be // 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 // 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); CustomTransformer customTransformer = customTransformersByName.get(transformName);
if (customTransformer == null) if (customTransformer == null)
@@ -666,21 +538,6 @@ public class TransformHandler
return customTransformer; 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, private ResponseEntity<StreamingResponseBody> createResponseEntity(String targetMimetype,
StreamingResponseBody body) StreamingResponseBody body)
{ {

View File

@@ -34,11 +34,12 @@ import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; 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 @Component
public class TransformManagerImpl implements TransformManager public class TransformManagerImpl implements TransformManager
@@ -52,27 +53,11 @@ public class TransformManagerImpl implements TransformManager
private String targetMimetype; private String targetMimetype;
private File sourceFile; private File sourceFile;
private File targetFile; private File targetFile;
private boolean keepTargetFile;
private boolean createSourceFileCalled; private boolean createSourceFileCalled;
private boolean createTargetFileCalled; private boolean createTargetFileCalled;
private boolean sourceFileCreated; private Boolean startedWithSourceFile;
private boolean targetFileCreated; private Boolean startedWithTargetFile;
private TransformManagerImpl()
{
}
public void init()
{
request = null;
inputStream = null;
outputStreamLengthRecorder = null;
sourceFile = null;
targetFile = null;
createSourceFileCalled = false;
createTargetFileCalled = false;
sourceFileCreated = false;
targetFileCreated = false;
}
public void setRequest(HttpServletRequest request) public void setRequest(HttpServletRequest request)
{ {
@@ -82,6 +67,10 @@ public class TransformManagerImpl implements TransformManager
public InputStream setInputStream(InputStream inputStream) public InputStream setInputStream(InputStream inputStream)
{ {
this.inputStream = inputStream; this.inputStream = inputStream;
if (startedWithSourceFile == null)
{
startedWithSourceFile = false;
}
return inputStream; return inputStream;
} }
@@ -92,8 +81,12 @@ public class TransformManagerImpl implements TransformManager
public OutputStream setOutputStream(OutputStream outputStream) public OutputStream setOutputStream(OutputStream outputStream)
{ {
this.outputStreamLengthRecorder = new OutputStreamLengthRecorder(outputStream); outputStreamLengthRecorder = new OutputStreamLengthRecorder(outputStream);
return outputStream; if (startedWithTargetFile == null)
{
startedWithTargetFile = false;
}
return outputStreamLengthRecorder;
} }
public Long getOutputLength() public Long getOutputLength()
@@ -119,27 +112,30 @@ public class TransformManagerImpl implements TransformManager
public void setSourceFile(File sourceFile) public void setSourceFile(File sourceFile)
{ {
this.sourceFile = sourceFile; this.sourceFile = sourceFile;
if (startedWithSourceFile == null)
{
startedWithSourceFile = true;
}
} }
public File getTargetFile() { public File getTargetFile()
{
return targetFile; return targetFile;
} }
File setTargetFile(File targetFile) File setTargetFile(File targetFile)
{ {
this.targetFile = targetFile; this.targetFile = targetFile;
if (startedWithTargetFile == null)
{
startedWithTargetFile = true;
}
return targetFile; return targetFile;
} }
public void keepTargetFile()
public void setTargetFileCreated()
{ {
targetFileCreated = true; keepTargetFile = true;
}
public void setSourceFileCreated()
{
sourceFileCreated = true;
} }
@Override public File createSourceFile() @Override public File createSourceFile()
@@ -153,7 +149,6 @@ public class TransformManagerImpl implements TransformManager
if (sourceFile == null) if (sourceFile == null)
{ {
sourceFile = FileManager.createSourceFile(request, inputStream, sourceMimetype); sourceFile = FileManager.createSourceFile(request, inputStream, sourceMimetype);
sourceFileCreated = true;
} }
return sourceFile; return sourceFile;
} }
@@ -169,36 +164,45 @@ public class TransformManagerImpl implements TransformManager
if (targetFile == null) if (targetFile == null)
{ {
targetFile = FileManager.createTargetFile(request, sourceMimetype, targetMimetype); targetFile = FileManager.createTargetFile(request, sourceMimetype, targetMimetype);
targetFileCreated = true;
} }
return targetFile; return targetFile;
} }
public void ifUsedCopyTargetFileToOutputStream() public void copyTargetFileToOutputStream() throws IOException
{ {
if (targetFileCreated) if (targetFile != null)
{
if (startedWithTargetFile == false)
{ {
FileManager.copyFileToOutputStream(targetFile, outputStreamLengthRecorder); 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()); logger.error("Failed to delete temporary source file "+sourceFile.getPath());
} }
sourceFile = null; 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()); logger.error("Failed to delete temporary target file "+targetFile.getPath());
} }
targetFile = null; targetFile = null;
targetFileCreated = false;
} }
@Override @Override
@@ -213,61 +217,4 @@ public class TransformManagerImpl implements TransformManager
// TODO send the current output as a TransformResponse and then start a new one. // TODO send the current output as a TransformResponse and then start a new one.
throw new UnsupportedOperationException("Not currently supported"); 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) 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.setSessionTransacted(true); // do we need this?
jmsTemplate.convertAndSend(destination, reply, m -> { jmsTemplate.convertAndSend(destination, reply, m -> {
m.setJMSCorrelationID(correlationId); m.setJMSCorrelationID(correlationId);
return m; return m;
}); });
logger.trace("Sent: {} - with correlation ID {}", reply, correlationId); 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); 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; return byteCount;
} }
public void setByteCount(long byteCount)
{
this.byteCount = byteCount;
}
public void write(int b) throws IOException public void write(int b) throws IOException
{ {
super.write(b); super.write(b);
@@ -53,6 +58,5 @@ public class OutputStreamLengthRecorder extends FilterOutputStream
public void write(byte b[], int off, int len) throws IOException public void write(byte b[], int off, int len) throws IOException
{ {
super.write(b, off, len); super.write(b, off, len);
byteCount += len;
} }
} }

View File

@@ -26,28 +26,29 @@
*/ */
package org.alfresco.transform.base; package org.alfresco.transform.base;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; import com.fasterxml.jackson.databind.ObjectMapper;
import static org.alfresco.transform.common.RequestParamMap.DIRECT_ACCESS_URL; import org.alfresco.transform.base.clients.AlfrescoSharedFileStoreClient;
import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM; import org.alfresco.transform.base.model.FileRefEntity;
import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM_CONFIG_LATEST; import org.alfresco.transform.base.model.FileRefResponse;
import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM_CONFIG; import org.alfresco.transform.base.probes.ProbeTransform;
import static org.hamcrest.Matchers.containsString; import org.alfresco.transform.client.model.InternalContext;
import static org.junit.jupiter.api.Assertions.assertEquals; import org.alfresco.transform.client.model.TransformReply;
import static org.junit.jupiter.api.Assertions.assertNotNull; import org.alfresco.transform.client.model.TransformRequest;
import static org.junit.jupiter.api.Assertions.assertTrue; import org.alfresco.transform.messages.TransformStack;
import static org.mockito.ArgumentMatchers.any; import org.alfresco.transform.registry.TransformServiceRegistry;
import static org.mockito.Mockito.when; import org.junit.jupiter.api.Test;
import static org.springframework.http.HttpHeaders.ACCEPT; import org.junit.jupiter.api.io.TempDir;
import static org.springframework.http.HttpHeaders.CONTENT_TYPE; import org.springframework.beans.factory.annotation.Autowired;
import static org.springframework.http.HttpStatus.BAD_REQUEST; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import static org.springframework.http.HttpStatus.CREATED; import org.springframework.boot.test.context.SpringBootTest;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; import org.springframework.boot.test.mock.mockito.MockBean;
import static org.springframework.http.HttpStatus.OK; import org.springframework.boot.test.mock.mockito.SpyBean;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import org.springframework.mock.web.MockMultipartFile;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import org.springframework.test.web.servlet.MvcResult;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request; import org.springframework.test.web.servlet.ResultActions;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@@ -57,47 +58,28 @@ import java.net.URL;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import org.alfresco.transform.base.probes.ProbeTransform; import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import org.alfresco.transform.client.model.InternalContext; import static org.alfresco.transform.common.RequestParamMap.DIRECT_ACCESS_URL;
import org.alfresco.transform.client.model.TransformReply; import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM;
import org.alfresco.transform.client.model.TransformRequest; import static org.hamcrest.Matchers.containsString;
import org.alfresco.transform.config.SupportedSourceAndTarget; import static org.junit.jupiter.api.Assertions.assertEquals;
import org.alfresco.transform.config.TransformConfig; import static org.mockito.ArgumentMatchers.any;
import org.alfresco.transform.config.TransformOption; import static org.mockito.Mockito.when;
import org.alfresco.transform.config.TransformOptionGroup; import static org.springframework.http.HttpHeaders.ACCEPT;
import org.alfresco.transform.config.TransformOptionValue; import static org.springframework.http.HttpHeaders.CONTENT_TYPE;
import org.alfresco.transform.config.Transformer; import static org.springframework.http.HttpStatus.BAD_REQUEST;
import org.alfresco.transform.registry.TransformServiceRegistry; import static org.springframework.http.HttpStatus.CREATED;
import org.alfresco.transform.messages.TransformStack; import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
import org.alfresco.transform.base.clients.AlfrescoSharedFileStoreClient; import static org.springframework.http.HttpStatus.OK;
import org.alfresco.transform.base.model.FileRefEntity; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import org.alfresco.transform.base.model.FileRefResponse; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
import org.junit.jupiter.api.Test; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import org.junit.jupiter.api.io.TempDir; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import org.springframework.beans.factory.annotation.Autowired; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request;
import org.springframework.beans.factory.annotation.Value; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
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;
/** /**
* Super class for testing. * Super class for testing.
@@ -106,7 +88,9 @@ import com.google.common.collect.ImmutableSet;
@AutoConfigureMockMvc @AutoConfigureMockMvc
public abstract class AbstractBaseTest 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; public File tempDir;
@Autowired @Autowired
@@ -159,6 +143,32 @@ public abstract class AbstractBaseTest
protected abstract void updateTransformRequestWithSpecificOptions(TransformRequest transformRequest); 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. * 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 * 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 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; File testFile = null;
ClassLoader classLoader = getClass().getClassLoader(); ClassLoader classLoader = AbstractBaseTest.class.getClassLoader();
URL testFileUrl = classLoader.getResource(testFilename); URL testFileUrl = classLoader.getResource(testFilename);
if (required && testFileUrl == null) if (required && testFileUrl == null)
{ {
throw new IOException("The test file " + testFilename + throw new IOException("The test file " + testFilename +
" does not exist in the resources directory"); " 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 // Added as part of ATS-702 to allow test resources to be read from the imported jar files to prevent test
if (testFileUrl!=null) // resource duplication
if (testFileUrl != null)
{ {
// Each use of the tempDir should result in a unique directory being used // Each use of the tempDir should result in a unique directory being used
testFile = new File(tempDir, testFilename); testFile = new File(tempDir, testFilename);
@@ -265,26 +281,19 @@ public abstract class AbstractBaseTest
protected TransformRequest createTransformRequest(String sourceFileRef, File sourceFile) protected TransformRequest createTransformRequest(String sourceFileRef, File sourceFile)
{ {
TransformRequest transformRequest = new TransformRequest(); return TransformRequest.builder()
transformRequest.setRequestId("1"); .withRequestId("1")
transformRequest.setSchema(1); .withSchema(1)
transformRequest.setClientData("Alfresco Digital Business Platform"); .withClientData("Alfresco Digital Business Platform")
transformRequest.setTransformRequestOptions(options); .withTransformRequestOptions(options)
transformRequest.setSourceReference(sourceFileRef); .withSourceReference(sourceFileRef)
transformRequest.setSourceExtension(sourceExtension); .withSourceExtension(sourceExtension)
transformRequest.setSourceMediaType(sourceMimetype); .withSourceMediaType(sourceMimetype)
transformRequest.setSourceSize(sourceFile.length()); .withSourceSize(sourceFile.length())
transformRequest.setTargetExtension(targetExtension); .withTargetExtension(targetExtension)
transformRequest.setTargetMediaType(targetMimetype); .withTargetMediaType(targetMimetype)
transformRequest.setInternalContext(InternalContext.initialise(null)); .withInternalContextForTransformEngineTests()
transformRequest.getInternalContext().getMultiStep().setInitialRequestId("123"); .build();
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;
} }
@Test @Test
@@ -339,28 +348,6 @@ public abstract class AbstractBaseTest
"attachment; filename*=UTF-8''transform." + targetExtension)); "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 @Test
public void calculateMaxTime() throws Exception public void calculateMaxTime() throws Exception
{ {
@@ -414,187 +401,6 @@ public abstract class AbstractBaseTest
assertEquals(BAD_REQUEST.value(), transformReply.getStatus()); 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 @Test
public void queueTransformRequestUsingDirectAccessUrlTest() throws Exception public void queueTransformRequestUsingDirectAccessUrlTest() throws Exception
{ {
@@ -609,7 +415,7 @@ public abstract class AbstractBaseTest
String directUrl = "file://" + sourceFile.toPath(); String directUrl = "file://" + sourceFile.toPath();
transformRequestOptions.put(DIRECT_ACCESS_URL, directUrl); transformRequestOptions.put(DIRECT_ACCESS_URL, directUrl);
transformRequest.setTransformRequestOptions(transformRequestOptions); // transformRequest.setTransformRequestOptions(transformRequestOptions);
when(alfrescoSharedFileStoreClient.saveFile(any())) when(alfrescoSharedFileStoreClient.saveFile(any()))
.thenReturn(new FileRefResponse(new FileRefEntity(targetFileRef))); .thenReturn(new FileRefResponse(new FileRefEntity(targetFileRef)));
@@ -621,15 +427,13 @@ public abstract class AbstractBaseTest
String tr = objectMapper.writeValueAsString(transformRequest); String tr = objectMapper.writeValueAsString(transformRequest);
String transformationReplyAsString = mockMvc String transformationReplyAsString = mockMvc
.perform(MockMvcRequestBuilders .perform(MockMvcRequestBuilders
.post("/transform") .post(ENDPOINT_TRANSFORM)
.header(ACCEPT, APPLICATION_JSON_VALUE) .header(ACCEPT, APPLICATION_JSON_VALUE)
.header(CONTENT_TYPE, APPLICATION_JSON_VALUE) .header(CONTENT_TYPE, APPLICATION_JSON_VALUE)
.content(tr)) .content(tr))
.andExpect(status().is(CREATED.value())) .andExpect(status().is(CREATED.value()))
.andReturn().getResponse().getContentAsString(); .andReturn().getResponse().getContentAsString();
TransformReply transformReply = objectMapper.readValue(transformationReplyAsString, TransformReply.class);
TransformReply transformReply = objectMapper.readValue(transformationReplyAsString,
TransformReply.class);
// Assert the reply // Assert the reply
assertEquals(transformRequest.getRequestId(), transformReply.getRequestId()); assertEquals(transformRequest.getRequestId(), transformReply.getRequestId());
@@ -643,11 +447,16 @@ public abstract class AbstractBaseTest
File dauSourceFile = getTestFile("quick." + sourceExtension, true); File dauSourceFile = getTestFile("quick." + sourceExtension, true);
String directUrl = "file://" + dauSourceFile.toPath(); String directUrl = "file://" + dauSourceFile.toPath();
ResultActions resultActions = mockMvc.perform( MvcResult mvcResult = mockMvc.perform(
mockMvcRequest(ENDPOINT_TRANSFORM, null) mockMvcRequest(ENDPOINT_TRANSFORM, null)
.param("targetExtension", targetExtension)
.param(DIRECT_ACCESS_URL, directUrl)) .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) 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 * 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 * @author Lucian Tuca
* created on 15/01/2019 * created on 15/01/2019
@@ -67,22 +68,6 @@ public abstract class AbstractQueueTest
{ {
TransformRequest request = buildRequest(); 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 -> { jmsTemplate.convertAndSend(engineRequestQueue, request, m -> {
m.setJMSCorrelationID(request.getRequestId()); m.setJMSCorrelationID(request.getRequestId());
m.setJMSReplyTo(testingQueue); m.setJMSReplyTo(testingQueue);

View File

@@ -61,7 +61,7 @@ import static org.springframework.http.MediaType.MULTIPART_FORM_DATA;
FakeTransformEngineWithTwoCustomTransformers.class, FakeTransformEngineWithTwoCustomTransformers.class,
FakeTransformerTxT2Pdf.class, FakeTransformerTxT2Pdf.class,
FakeTransformerPdf2Png.class}) FakeTransformerPdf2Png.class})
public class HttpTest public class RestTest
{ {
@Autowired @Autowired
private TestRestTemplate restTemplate; private TestRestTemplate restTemplate;

View File

@@ -26,19 +26,19 @@
*/ */
package org.alfresco.transform.base; package org.alfresco.transform.base;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.alfresco.transform.base.fakes.FakeTransformEngineWithAllInOne; import org.alfresco.transform.base.fakes.FakeTransformEngineWithAllInOne;
import org.alfresco.transform.base.fakes.FakeTransformEngineWithOneCustomTransformer; import org.alfresco.transform.base.fakes.FakeTransformEngineWithOneCustomTransformer;
import org.alfresco.transform.base.fakes.FakeTransformEngineWithTwoCustomTransformers; import org.alfresco.transform.base.fakes.FakeTransformEngineWithTwoCustomTransformers;
import org.alfresco.transform.base.fakes.FakeTransformerPdf2Jpg; import org.alfresco.transform.base.fakes.FakeTransformerPdf2Jpg;
import org.alfresco.transform.base.fakes.FakeTransformerPdf2Png; import org.alfresco.transform.base.fakes.FakeTransformerPdf2Png;
import org.alfresco.transform.base.fakes.FakeTransformerTxT2Pdf; 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.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; 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.mock.web.MockMultipartFile;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; 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.hamcrest.Matchers.containsString;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull; 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.request.MockMvcRequestBuilders.asyncDispatch;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; 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.header;
@@ -77,10 +73,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 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. * 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 @AutoConfigureMockMvc
@SpringBootTest(classes={org.alfresco.transform.base.Application.class}) @SpringBootTest(classes={org.alfresco.transform.base.Application.class})
@@ -103,7 +99,7 @@ public class TransformControllerAllInOneTest
private String coreVersion; private String coreVersion;
@Test @Test
public void testInitEngine() throws Exception public void testInitEngine()
{ {
assertEquals(FakeTransformEngineWithAllInOne.class.getSimpleName(), assertEquals(FakeTransformEngineWithAllInOne.class.getSimpleName(),
transformController.transformEngine.getClass().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 ch.qos.logback.core.AppenderBase;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableMap; 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.FakeTransformEngineWithTwoCustomTransformers;
import org.alfresco.transform.base.fakes.FakeTransformerPdf2Png; import org.alfresco.transform.base.fakes.FakeTransformerPdf2Png;
import org.alfresco.transform.base.fakes.FakeTransformerTxT2Pdf; 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.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.Test;
import org.junit.jupiter.api.io.TempDir;
import org.mockito.stubbing.Answer;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest; 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.mock.web.MockMultipartFile;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import java.io.File;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner; import java.util.StringJoiner;
import java.util.UUID;
import java.util.stream.Collectors; 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_IMAGE_BMP;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_PDF; import static org.alfresco.transform.common.Mimetype.MIMETYPE_PDF;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_TEXT_PLAIN; 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.ArgumentMatchers.eq;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify; 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.request.MockMvcRequestBuilders.asyncDispatch;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; 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.header;
@@ -83,7 +107,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 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}. * Also see {@link TransformControllerAllInOneTest}.
*/ */
@@ -103,6 +128,29 @@ public class TransformControllerTest
protected ObjectMapper objectMapper; protected ObjectMapper objectMapper;
@Autowired @Autowired
private String coreVersion; 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 @Test
public void testInitEngine() throws Exception public void testInitEngine() throws Exception
@@ -228,6 +276,7 @@ public class TransformControllerTest
TransformConfig config = objectMapper.readValue( TransformConfig config = objectMapper.readValue(
mockMvc.perform(MockMvcRequestBuilders.get(url)) mockMvc.perform(MockMvcRequestBuilders.get(url))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(header().string(CONTENT_TYPE, APPLICATION_JSON_VALUE))
.andReturn() .andReturn()
.getResponse() .getResponse()
.getContentAsString(), TransformConfig.class); .getContentAsString(), TransformConfig.class);
@@ -248,7 +297,44 @@ public class TransformControllerTest
} }
@Test @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( MvcResult mvcResult = mockMvc.perform(
MockMvcRequestBuilders.multipart(ENDPOINT_TRANSFORM) MockMvcRequestBuilders.multipart(ENDPOINT_TRANSFORM)
@@ -268,7 +354,7 @@ public class TransformControllerTest
} }
@Test @Test
public void testTestTransformEndpointConvertsRequestParameters() throws Exception public void testTestTransformEndpointWhichConvertsRequestParameters() throws Exception
{ {
TransformHandler orig = transformController.transformHandler; TransformHandler orig = transformController.transformHandler;
try try

View File

@@ -26,9 +26,34 @@
*/ */
package org.alfresco.transform.base; 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.beans.factory.annotation.Autowired;
import org.springframework.test.web.servlet.MockMvc; 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 public class TransformHandlerTest
{ {
@Autowired @Autowired
@@ -36,4 +61,64 @@ public class TransformHandlerTest
@Autowired @Autowired
private TransformHandler transformHandler; 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") .withClientData("ACS")
.withSourceReference(UUID.randomUUID().toString()) .withSourceReference(UUID.randomUUID().toString())
.withSourceSize(32L) .withSourceSize(32L)
.withInternalContextForTransformEngineTests()
.build(); .build();
} }
} }

View File

@@ -132,12 +132,6 @@ public class ImageMagickTest extends AbstractBaseTest
mockTransformCommand("jpg", "png", "image/jpg", true); mockTransformCommand("jpg", "png", "image/jpg", true);
} }
@Override
public String getEngineConfigName()
{
return ENGINE_CONFIG_NAME;
}
@Override @Override
protected void mockTransformCommand(String sourceExtension, protected void mockTransformCommand(String sourceExtension,
String targetExtension, String sourceMimetype, String targetExtension, String sourceMimetype,

View File

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

View File

@@ -168,12 +168,6 @@ public class LibreOfficeTest extends AbstractBaseTest
// ReflectionTestUtils.setField(controller, "javaExecutor", javaExecutor); // ReflectionTestUtils.setField(controller, "javaExecutor", javaExecutor);
// } // }
@Override
public String getEngineConfigName()
{
return ENGINE_CONFIG_NAME;
}
@Override @Override
protected void mockTransformCommand(String sourceExtension, String targetExtension, protected void mockTransformCommand(String sourceExtension, String targetExtension,
String sourceMimetype, boolean readTargetFileBytes) 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.alfresco.transform.base.metadataExtractors.AbstractMetadataExtractor;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.mail.Header; import javax.mail.Header;
import javax.mail.internet.InternetAddress; import javax.mail.internet.InternetAddress;
@@ -71,6 +72,7 @@ import static org.alfresco.transform.base.metadataExtractors.AbstractMetadataExt
* @author Derek Hulley * @author Derek Hulley
* @author adavis * @author adavis
*/ */
@Component
public class RFC822MetadataExtractor extends AbstractMetadataExtractor implements CustomTransformer public class RFC822MetadataExtractor extends AbstractMetadataExtractor implements CustomTransformer
{ {
private static final Logger logger = LoggerFactory.getLogger(RFC822MetadataExtractor.class); private static final Logger logger = LoggerFactory.getLogger(RFC822MetadataExtractor.class);

View File

@@ -48,6 +48,8 @@ public class MiscQueueTest extends AbstractQueueTest
.withSchema(1) .withSchema(1)
.withClientData("ACS") .withClientData("ACS")
.withSourceReference(UUID.randomUUID().toString()) .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.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue; 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.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 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); sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype, sourceFileBytes);
} }
@Override
public String getEngineConfigName()
{
return ENGINE_CONFIG_NAME;
}
@Override @Override
protected void mockTransformCommand(String sourceExtension, String targetExtension, protected void mockTransformCommand(String sourceExtension, String targetExtension,
String sourceMimetype, boolean readTargetFileBytes) String sourceMimetype, boolean readTargetFileBytes)

View File

@@ -52,6 +52,8 @@ public class PdfRendererQueueTest extends AbstractQueueTest
.withSchema(1) .withSchema(1)
.withClientData("ACS") .withClientData("ACS")
.withSourceReference(UUID.randomUUID().toString()) .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); ReflectionTestUtils.setField(controller, "commandExecutor", commandExecutor);
} }
@Override
public String getEngineConfigName()
{
return ENGINE_CONFIG_NAME;
}
@Override @Override
public void mockTransformCommand(String sourceExtension, public void mockTransformCommand(String sourceExtension,
String targetExtension, String sourceMimetype, String targetExtension, String sourceMimetype,

View File

@@ -49,10 +49,9 @@ import org.springframework.http.ResponseEntity;
/** /**
* @author Cezar Leahu * @author Cezar Leahu
*/ */
public class AlfrescoPdfRendererTransformationIT public class PdfRendererTransformationIT
{ {
private static final Logger logger = LoggerFactory.getLogger( private static final Logger logger = LoggerFactory.getLogger(PdfRendererTransformationIT.class);
AlfrescoPdfRendererTransformationIT.class);
private static final String ENGINE_URL = "http://localhost:8090"; private static final String ENGINE_URL = "http://localhost:8090";
private static final Map<String, FileInfo> TEST_FILES = Stream.of( private static final Map<String, FileInfo> TEST_FILES = Stream.of(

View File

@@ -52,6 +52,8 @@ public class TikaQueueTest extends AbstractQueueTest
.withSchema(1) .withSchema(1)
.withClientData("ACS") .withClientData("ACS")
.withSourceReference(UUID.randomUUID().toString()) .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.executors.RuntimeExec;
import org.alfresco.transform.base.model.FileRefEntity; import org.alfresco.transform.base.model.FileRefEntity;
import org.alfresco.transform.base.model.FileRefResponse; 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.TransformReply;
import org.alfresco.transform.client.model.TransformRequest; import org.alfresco.transform.client.model.TransformRequest;
import org.apache.poi.ooxml.POIXMLProperties; 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.HttpHeaders;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.mock.web.MockMultipartFile; 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.MvcResult;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
@@ -145,12 +143,6 @@ public class TikaTest extends AbstractBaseTest
targetMimetype = MIMETYPE_TEXT_PLAIN; targetMimetype = MIMETYPE_TEXT_PLAIN;
} }
@Override
public String getEngineConfigName()
{
return ENGINE_CONFIG_NAME;
}
@Override @Override
protected void mockTransformCommand(String sourceExtension, protected void mockTransformCommand(String sourceExtension,
String targetExtension, String sourceMimetype, String targetExtension, String sourceMimetype,
@@ -166,57 +158,7 @@ public class TikaTest extends AbstractBaseTest
expectedTargetFileBytes = readTargetFileBytes ? readTestFile(targetExtension) : null; expectedTargetFileBytes = readTargetFileBytes ? readTestFile(targetExtension) : null;
sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype, sourceFileBytes); sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype, sourceFileBytes);
when(mockTransformCommand.execute(any(), anyLong())).thenAnswer( // Tika transform is not mocked. It is run for real.
(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;
});
when(mockExecutionResult.getExitValue()).thenReturn(0); when(mockExecutionResult.getExitValue()).thenReturn(0);
when(mockExecutionResult.getStdErr()).thenReturn("STDERROR"); when(mockExecutionResult.getStdErr()).thenReturn("STDERROR");
@@ -295,22 +237,6 @@ public class TikaTest extends AbstractBaseTest
super.noExtensionSourceFilenameTest(); 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 @Test
@Override @Override
public void calculateMaxTime() throws Exception public void calculateMaxTime() throws Exception

View File

@@ -21,11 +21,18 @@
*/ */
package org.alfresco.transform.client.model; package org.alfresco.transform.client.model;
import org.alfresco.transform.common.ExtensionService;
import org.alfresco.transform.messages.TransformStack;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects; 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 // 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. // org.alfresco.transform.client.model in Alfresco for backward compatibility.
public class TransformRequest implements Serializable 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() public static Builder builder()
{ {
return new Builder(); return new Builder();
@@ -267,6 +293,14 @@ public class TransformRequest implements Serializable
return this; 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() public TransformRequest build()
{ {
return request; return request;

View File

@@ -88,7 +88,7 @@ class TransformStackTest
{ {
MockitoAnnotations.openMocks(this); MockitoAnnotations.openMocks(this);
// Repeat what is done by Router.initialiseContext // Repeat what is done by Router.initialiseContextWhenReceivedByRouter
internalContext.setMultiStep(new MultiStep()); internalContext.setMultiStep(new MultiStep());
internalContext.getMultiStep().setTransformsToBeDone(new ArrayList<>()); internalContext.getMultiStep().setTransformsToBeDone(new ArrayList<>());
TransformStack.setInitialTransformRequestOptions(internalContext, options); TransformStack.setInitialTransformRequestOptions(internalContext, options);

View File

@@ -21,15 +21,20 @@
*/ */
package org.alfresco.transform.registry; package org.alfresco.transform.registry;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import org.alfresco.transform.common.TransformConfigResourceReader;
import org.alfresco.transform.config.SupportedSourceAndTarget; import org.alfresco.transform.config.SupportedSourceAndTarget;
import org.alfresco.transform.config.TransformConfig; import org.alfresco.transform.config.TransformConfig;
import org.alfresco.transform.config.TransformStep; import org.alfresco.transform.config.TransformStep;
import org.alfresco.transform.config.Transformer; import org.alfresco.transform.config.Transformer;
import org.junit.Test; 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.List;
import java.util.Set; 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) private String expectedWildcardError(String errorReason)
{ {
@@ -889,8 +903,62 @@ public class CombinedTransformConfigTest
config.addTransformConfig(transformConfig, READ_FROM_B, BASE_URL_B, registry); config.addTransformConfig(transformConfig, READ_FROM_B, BASE_URL_B, registry);
config.combineTransformerConfig(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(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}. * 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 READ_FROM_A = "readFromA";
private static final String BASE_URL_B = "baseUrlB"; 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 CombinedTransformConfig config = new CombinedTransformConfig();
private final TestTransformRegistry registry = new TestTransformRegistry(); private final FakeTransformRegistry registry = new FakeTransformRegistry();
@Test @Test
public void testRemoveTransformers() public void testRemoveTransformers()