mirror of
https://github.com/Alfresco/alfresco-transform-core.git
synced 2025-08-14 17:58:27 +00:00
Save point: [skip ci]
* HttpStatus
This commit is contained in:
@@ -29,21 +29,13 @@ package org.alfresco.transform.base;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.event.EventListener;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.alfresco.transform.base.logging.StandardMessages.COMMUNITY_LICENCE;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class})
|
||||
|
@@ -111,7 +111,7 @@ public class QueueTransformService
|
||||
catch (TransformException e)
|
||||
{
|
||||
logger.error(e.getMessage(), e);
|
||||
replyWithError(replyToDestinationQueue, HttpStatus.valueOf(e.getStatusCode()),
|
||||
replyWithError(replyToDestinationQueue, HttpStatus.valueOf(e.getStatusCode().value()),
|
||||
e.getMessage(), correlationId);
|
||||
return;
|
||||
}
|
||||
@@ -148,23 +148,21 @@ public class QueueTransformService
|
||||
String message =
|
||||
"MessageConversionException during T-Request deserialization of message with correlationID "
|
||||
+ correlationId + ": ";
|
||||
throw new TransformException(BAD_REQUEST.value(), message + e.getMessage());
|
||||
throw new TransformException(BAD_REQUEST, message + e.getMessage());
|
||||
}
|
||||
catch (JMSException e)
|
||||
{
|
||||
String message =
|
||||
"JMSException during T-Request deserialization of message with correlationID "
|
||||
+ correlationId + ": ";
|
||||
throw new TransformException(INTERNAL_SERVER_ERROR.value(),
|
||||
message + e.getMessage());
|
||||
throw new TransformException(INTERNAL_SERVER_ERROR, message + e.getMessage());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
String message =
|
||||
"Exception during T-Request deserialization of message with correlationID "
|
||||
+ correlationId + ": ";
|
||||
throw new TransformException(INTERNAL_SERVER_ERROR.value(),
|
||||
message + e.getMessage());
|
||||
throw new TransformException(INTERNAL_SERVER_ERROR, message + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -195,7 +195,7 @@ public class TransformController
|
||||
}
|
||||
|
||||
@PostMapping(value = ENDPOINT_TRANSFORM, consumes = MULTIPART_FORM_DATA_VALUE)
|
||||
public StreamingResponseBody transform(HttpServletRequest request,
|
||||
public ResponseEntity<StreamingResponseBody> transform(HttpServletRequest request,
|
||||
@RequestParam(value = FILE, required = false) MultipartFile sourceMultipartFile,
|
||||
@RequestParam(value = SOURCE_MIMETYPE, required = false) String sourceMimetype,
|
||||
@RequestParam(value = TARGET_MIMETYPE, required = false) String targetMimetype,
|
||||
@@ -206,7 +206,7 @@ public class TransformController
|
||||
}
|
||||
|
||||
@PostMapping(value = ENDPOINT_TEST, consumes = MULTIPART_FORM_DATA_VALUE)
|
||||
public StreamingResponseBody testTransform(HttpServletRequest request,
|
||||
public ResponseEntity<StreamingResponseBody> testTransform(HttpServletRequest request,
|
||||
@RequestParam(value = FILE, required = false) MultipartFile sourceMultipartFile,
|
||||
@RequestParam(value = SOURCE_MIMETYPE, required = false) String sourceMimetype,
|
||||
@RequestParam(value = TARGET_MIMETYPE, required = false) String targetMimetype,
|
||||
@@ -274,7 +274,7 @@ public class TransformController
|
||||
throws IOException
|
||||
{
|
||||
final String message = e.getMessage();
|
||||
final int statusCode = e.getStatusCode();
|
||||
final int statusCode = e.getStatusCode().value();
|
||||
|
||||
logger.error(message);
|
||||
long time = LogEntry.setStatusCodeAndMessage(statusCode, message);
|
||||
|
@@ -35,6 +35,7 @@ import org.alfresco.transform.base.util.OutputStreamLengthRecorder;
|
||||
import org.alfresco.transform.client.model.InternalContext;
|
||||
import org.alfresco.transform.client.model.TransformReply;
|
||||
import org.alfresco.transform.client.model.TransformRequest;
|
||||
import org.alfresco.transform.common.ExtensionService;
|
||||
import org.alfresco.transform.common.TransformException;
|
||||
import org.alfresco.transform.common.TransformerDebug;
|
||||
import org.alfresco.transform.messages.TransformRequestValidator;
|
||||
@@ -43,9 +44,9 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.ContentDisposition;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.DirectFieldBindingResult;
|
||||
@@ -62,6 +63,7 @@ import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
@@ -70,23 +72,18 @@ import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static java.util.stream.Collectors.joining;
|
||||
import static org.alfresco.transform.base.fs.FileManager.TempFileProvider.createTempFile;
|
||||
import static org.alfresco.transform.base.fs.FileManager.createTargetFile;
|
||||
import static org.alfresco.transform.base.fs.FileManager.deleteFile;
|
||||
import static org.alfresco.transform.base.fs.FileManager.getDirectAccessUrlInputStream;
|
||||
import static org.alfresco.transform.base.fs.FileManager.getFilenameFromContentDisposition;
|
||||
import static org.alfresco.transform.base.fs.FileManager.save;
|
||||
import static org.alfresco.transform.common.RequestParamMap.DIRECT_ACCESS_URL;
|
||||
import static org.alfresco.transform.common.RequestParamMap.SOURCE_ENCODING;
|
||||
import static org.alfresco.transform.common.RequestParamMap.SOURCE_EXTENSION;
|
||||
import static org.alfresco.transform.common.RequestParamMap.SOURCE_MIMETYPE;
|
||||
import static org.alfresco.transform.common.RequestParamMap.TARGET_ENCODING;
|
||||
import static org.alfresco.transform.common.RequestParamMap.TARGET_MIMETYPE;
|
||||
import static org.springframework.http.HttpStatus.BAD_REQUEST;
|
||||
import static org.springframework.http.HttpStatus.CREATED;
|
||||
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
|
||||
import static org.springframework.http.HttpStatus.OK;
|
||||
import static org.springframework.util.StringUtils.getFilenameExtension;
|
||||
|
||||
/**
|
||||
* Handles the transform requests from either http or a message.
|
||||
@@ -178,39 +175,44 @@ public class TransformHandler
|
||||
return probeTestTransform;
|
||||
}
|
||||
|
||||
public StreamingResponseBody handleHttpRequest(HttpServletRequest request, MultipartFile sourceMultipartFile,
|
||||
String sourceMimetype, String targetMimetype, Map<String, String> requestParameters)
|
||||
public ResponseEntity<StreamingResponseBody> handleHttpRequest(HttpServletRequest request,
|
||||
MultipartFile sourceMultipartFile, String sourceMimetype, String targetMimetype,
|
||||
Map<String, String> requestParameters)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
return createResponseEntity(targetMimetype, os ->
|
||||
{
|
||||
logger.debug("Processing request via HTTP endpoint. Params: sourceMimetype: '{}', targetMimetype: '{}', "
|
||||
+ "requestParameters: {}", sourceMimetype, targetMimetype, requestParameters);
|
||||
}
|
||||
probeTestTransform.incrementTransformerCount();
|
||||
TransformManagerImpl transformManager = null;
|
||||
String reference = "e" + httpRequestCount.getAndIncrement();
|
||||
|
||||
final String directUrl = requestParameters.getOrDefault(DIRECT_ACCESS_URL, "");
|
||||
InputStream inputStream = new BufferedInputStream(directUrl.isBlank()
|
||||
? FileManager.getMultipartFileInputStream(sourceMultipartFile)
|
||||
: getDirectAccessUrlInputStream(directUrl));
|
||||
long sourceSizeInBytes = -1L; // TODO pass in t-options or just ignore for http request as the repo will have checked.
|
||||
Map<String, String> transformOptions = getTransformOptions(requestParameters);
|
||||
String transformName = getTransformerName(sourceSizeInBytes, sourceMimetype, targetMimetype, transformOptions);
|
||||
CustomTransformer customTransformer = getCustomTransformer(transformName);
|
||||
String reference = "e"+httpRequestCount.getAndIncrement();
|
||||
transformerDebug.pushTransform(reference, sourceMimetype, targetMimetype, sourceSizeInBytes, transformName);
|
||||
transformerDebug.logOptions(reference, requestParameters);
|
||||
|
||||
return os -> {
|
||||
OutputStreamLengthRecorder outputStream = new OutputStreamLengthRecorder(os);
|
||||
try
|
||||
{
|
||||
TransformManagerImpl transformManager = TransformManagerImpl.builder()
|
||||
.withRequest(request)
|
||||
.withSourceMimetype(sourceMimetype)
|
||||
.withTargetMimetype(targetMimetype)
|
||||
.withInputStream(inputStream)
|
||||
.withOutputStream(outputStream)
|
||||
.build();
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Processing request via HTTP endpoint. Params: sourceMimetype: '{}', targetMimetype: '{}', "
|
||||
+ "requestParameters: {}", sourceMimetype, targetMimetype, requestParameters);
|
||||
}
|
||||
probeTestTransform.incrementTransformerCount();
|
||||
|
||||
final String directUrl = requestParameters.getOrDefault(DIRECT_ACCESS_URL, "");
|
||||
InputStream inputStream = new BufferedInputStream(directUrl.isBlank() ?
|
||||
FileManager.getMultipartFileInputStream(sourceMultipartFile) :
|
||||
getDirectAccessUrlInputStream(directUrl));
|
||||
long sourceSizeInBytes = -1L; // Ignore for http requests as the Alfresco repo will have checked.
|
||||
Map<String, String> transformOptions = getTransformOptions(requestParameters);
|
||||
String transformName = getTransformerName(sourceSizeInBytes, sourceMimetype, targetMimetype, transformOptions);
|
||||
CustomTransformer customTransformer = getCustomTransformer(transformName);
|
||||
transformerDebug.pushTransform(reference, sourceMimetype, targetMimetype, sourceSizeInBytes, transformName);
|
||||
transformerDebug.logOptions(reference, requestParameters);
|
||||
|
||||
OutputStreamLengthRecorder outputStream = new OutputStreamLengthRecorder(os);
|
||||
transformManager = TransformManagerImpl.builder()
|
||||
.withRequest(request)
|
||||
.withSourceMimetype(sourceMimetype)
|
||||
.withTargetMimetype(targetMimetype)
|
||||
.withInputStream(inputStream)
|
||||
.withOutputStream(outputStream)
|
||||
.build();
|
||||
transformManager.setOutputStream(outputStream);
|
||||
|
||||
customTransformer.transform(sourceMimetype, inputStream,
|
||||
targetMimetype, outputStream, transformOptions, transformManager);
|
||||
@@ -220,127 +222,122 @@ public class TransformHandler
|
||||
LogEntry.setTargetSize(outputStream.getLength());
|
||||
long time = LogEntry.setStatusCodeAndMessage(OK.value(), "Success");
|
||||
|
||||
transformManager.deleteSourceFileIfExists();
|
||||
transformManager.deleteTargetFileIfExists();
|
||||
|
||||
probeTestTransform.recordTransformTime(time);
|
||||
transformerDebug.popTransform(reference, time);
|
||||
}
|
||||
catch (TransformException e)
|
||||
{
|
||||
transformerDebug.logFailure(reference, e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
transformerDebug.logFailure(reference, e.getMessage());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
finally
|
||||
{
|
||||
deleteTmpFiles(transformManager);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ResponseEntity<TransformReply> handleMessageRequest(TransformRequest request, Long timeout)
|
||||
{
|
||||
long start = System.currentTimeMillis();
|
||||
logger.trace("Received {}, timeout {} ms", request, timeout);
|
||||
probeTestTransform.incrementTransformerCount();
|
||||
TransformReply reply = createBasicTransformReply(request);
|
||||
|
||||
if (isTransformRequestValid(request, reply) == false)
|
||||
{
|
||||
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
|
||||
}
|
||||
|
||||
InputStream inputStream = getInputStream(request, reply);
|
||||
if (inputStream == null)
|
||||
{
|
||||
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
|
||||
}
|
||||
InputStream inputStream = null;
|
||||
TransformManagerImpl transformManager = null;
|
||||
TransformReply reply = createBasicTransformReply(request);;
|
||||
|
||||
try
|
||||
{
|
||||
logger.trace("Received {}, timeout {} ms", request, timeout);
|
||||
probeTestTransform.incrementTransformerCount();
|
||||
checkTransformRequestValid(request, reply);
|
||||
inputStream = getInputStream(request, reply);
|
||||
String targetMimetype = request.getTargetMediaType();
|
||||
String sourceMimetype = request.getSourceMediaType();
|
||||
File targetFile = createTargetFile(null, sourceMimetype, targetMimetype);
|
||||
transformerDebug.pushTransform(request);
|
||||
|
||||
long sourceSizeInBytes = request.getSourceSize();
|
||||
Map<String, String> transformOptions = getTransformOptions(request.getTransformRequestOptions());
|
||||
transformerDebug.logOptions(request);
|
||||
String transformName = getTransformerName(sourceSizeInBytes, sourceMimetype, targetMimetype, transformOptions);
|
||||
CustomTransformer customTransformer = getCustomTransformer(transformName);
|
||||
|
||||
try (OutputStreamLengthRecorder outputStream = new OutputStreamLengthRecorder(new BufferedOutputStream(
|
||||
new FileOutputStream(targetFile))))
|
||||
{
|
||||
long sourceSizeInBytes = request.getSourceSize();
|
||||
Map<String, String> transformOptions = getTransformOptions(request.getTransformRequestOptions());
|
||||
transformerDebug.logOptions(request);
|
||||
String transformName = getTransformerName(sourceSizeInBytes, sourceMimetype, targetMimetype, transformOptions);
|
||||
CustomTransformer customTransformer = getCustomTransformer(transformName);
|
||||
transformManager = TransformManagerImpl.builder()
|
||||
.withSourceMimetype(sourceMimetype)
|
||||
.withTargetMimetype(targetMimetype)
|
||||
.withInputStream(inputStream)
|
||||
.withOutputStream(outputStream)
|
||||
.withTargetFile(targetFile)
|
||||
.build();
|
||||
|
||||
TransformManagerImpl transformManager = TransformManagerImpl.builder()
|
||||
.withSourceMimetype(sourceMimetype)
|
||||
.withTargetMimetype(targetMimetype)
|
||||
.withInputStream(inputStream)
|
||||
.withOutputStream(outputStream)
|
||||
.withTargetFile(targetFile)
|
||||
.build();
|
||||
|
||||
customTransformer.transform(sourceMimetype, inputStream,
|
||||
targetMimetype, outputStream, transformOptions, transformManager);
|
||||
customTransformer.transform(sourceMimetype, inputStream, targetMimetype, outputStream, transformOptions,
|
||||
transformManager);
|
||||
|
||||
transformManager.ifUsedCopyTargetFileToOutputStream();
|
||||
|
||||
reply.getInternalContext().setCurrentSourceSize(outputStream.getLength());
|
||||
|
||||
if (saveTargetFileInSharedFileStore(targetFile, reply) == false)
|
||||
{
|
||||
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
|
||||
}
|
||||
|
||||
transformManager.deleteSourceFileIfExists();
|
||||
transformManager.deleteTargetFileIfExists();
|
||||
|
||||
probeTestTransform.recordTransformTime(System.currentTimeMillis()-start);
|
||||
transformerDebug.popTransform(reply);
|
||||
|
||||
logger.trace("Sending successful {}, timeout {} ms", reply, timeout);
|
||||
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
|
||||
}
|
||||
catch (TransformException e)
|
||||
{
|
||||
reply.setStatus(e.getStatusCode());
|
||||
reply.setErrorDetails(messageWithCause("Failed at processing transformation", e));
|
||||
|
||||
transformerDebug.logFailure(reply);
|
||||
logger.trace("Failed to perform transform (TransformException), sending " + reply, e);
|
||||
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
reply.setStatus(INTERNAL_SERVER_ERROR.value());
|
||||
reply.setErrorDetails(messageWithCause("Failed at processing transformation", e));
|
||||
|
||||
transformerDebug.logFailure(reply);
|
||||
logger.trace("Failed to perform transform (Exception), sending " + reply, e);
|
||||
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
|
||||
saveTargetFileInSharedFileStore(targetFile, reply);
|
||||
}
|
||||
}
|
||||
catch (TransformException e)
|
||||
{
|
||||
return createFailedResponseEntity(reply, e, e.getStatusCode().value());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return createFailedResponseEntity(reply, e, INTERNAL_SERVER_ERROR.value());
|
||||
}
|
||||
finally
|
||||
{
|
||||
deleteTmpFiles(transformManager);
|
||||
closeInputStreamWithoutException(inputStream);
|
||||
|
||||
probeTestTransform.recordTransformTime(System.currentTimeMillis()-start);
|
||||
transformerDebug.popTransform(reply);
|
||||
|
||||
logger.trace("Sending successful {}, timeout {} ms", reply, timeout);
|
||||
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isTransformRequestValid(TransformRequest request, TransformReply reply)
|
||||
private ResponseEntity<TransformReply> createFailedResponseEntity(TransformReply reply, Exception e,
|
||||
int status) {
|
||||
reply.setStatus(status);
|
||||
reply.setErrorDetails(messageWithCause("Transform failed", e));
|
||||
|
||||
transformerDebug.logFailure(reply);
|
||||
logger.trace("Transform failed. Sending " + reply, e);
|
||||
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
|
||||
}
|
||||
|
||||
private void deleteTmpFiles(TransformManagerImpl transformManager)
|
||||
{
|
||||
if (transformManager != null)
|
||||
{
|
||||
transformManager.deleteSourceFileIfExists();
|
||||
transformManager.deleteTargetFileIfExists();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkTransformRequestValid(TransformRequest request, TransformReply reply)
|
||||
{
|
||||
final Errors errors = validateTransformRequest(request);
|
||||
validateInternalContext(request, errors);
|
||||
reply.setInternalContext(request.getInternalContext());
|
||||
|
||||
if (!errors.getAllErrors().isEmpty())
|
||||
{
|
||||
reply.setStatus(BAD_REQUEST.value());
|
||||
reply.setErrorDetails(errors
|
||||
.getAllErrors()
|
||||
.stream()
|
||||
.map(Object::toString)
|
||||
.collect(joining(", ")));
|
||||
|
||||
transformerDebug.logFailure(reply);
|
||||
logger.trace("Invalid request, sending {}", reply);
|
||||
return false;
|
||||
String errorDetails = errors.getAllErrors().stream().map(Object::toString).collect(joining(", "));
|
||||
throw new TransformException(BAD_REQUEST, errorDetails);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private TransformReply createBasicTransformReply(TransformRequest request)
|
||||
@@ -393,7 +390,7 @@ public class TransformHandler
|
||||
{
|
||||
String message = "Source file with reference: " + sourceReference + " is null or empty.";
|
||||
logger.warn(message);
|
||||
throw new TransformException(BAD_REQUEST.value(), message);
|
||||
throw new TransformException(BAD_REQUEST, message);
|
||||
}
|
||||
|
||||
try
|
||||
@@ -404,40 +401,30 @@ public class TransformHandler
|
||||
{
|
||||
String message = "Shared File Store reference is invalid.";
|
||||
logger.warn(message);
|
||||
throw new TransformException(BAD_REQUEST.value(), message, e);
|
||||
throw new TransformException(BAD_REQUEST, message, e);
|
||||
}
|
||||
}
|
||||
|
||||
private InputStream getInputStream(TransformRequest request, TransformReply reply)
|
||||
{
|
||||
final String directUrl = request.getTransformRequestOptions().getOrDefault(DIRECT_ACCESS_URL, "");
|
||||
InputStream inputStream = null;
|
||||
try
|
||||
{
|
||||
inputStream = new BufferedInputStream(directUrl.isBlank()
|
||||
return new BufferedInputStream(directUrl.isBlank()
|
||||
? getSharedFileStoreInputStream(request.getSourceReference())
|
||||
: getDirectAccessUrlInputStream(directUrl));
|
||||
}
|
||||
catch (TransformException e)
|
||||
{
|
||||
reply.setStatus(e.getStatusCode());
|
||||
reply.setErrorDetails(messageWithCause("Failed at reading the source file", e));
|
||||
|
||||
transformerDebug.logFailure(reply);
|
||||
logger.trace("Failed to load source file (TransformException), sending " + reply);
|
||||
throw new TransformException(e.getStatusCode(), messageWithCause("Failed to read the source", e));
|
||||
}
|
||||
catch (HttpClientErrorException e)
|
||||
{
|
||||
reply.setStatus(e.getStatusCode().value());
|
||||
reply.setErrorDetails(messageWithCause("Failed at reading the source file", e));
|
||||
|
||||
transformerDebug.logFailure(reply);
|
||||
logger.trace("Failed to load source file (HttpClientErrorException), sending " + reply, e);
|
||||
throw new TransformException(e.getStatusCode(), messageWithCause("Failed to read the source", e));
|
||||
}
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
private boolean saveTargetFileInSharedFileStore(File targetFile, TransformReply reply)
|
||||
private void saveTargetFileInSharedFileStore(File targetFile, TransformReply reply)
|
||||
{
|
||||
FileRefResponse targetRef;
|
||||
try
|
||||
@@ -446,81 +433,19 @@ public class TransformHandler
|
||||
}
|
||||
catch (TransformException e)
|
||||
{
|
||||
reply.setStatus(e.getStatusCode());
|
||||
reply.setErrorDetails(messageWithCause("Failed at writing the transformed file", e));
|
||||
|
||||
transformerDebug.logFailure(reply);
|
||||
logger.trace("Failed to save target file (TransformException), sending " + reply, e);
|
||||
return false;
|
||||
throw new TransformException(e.getStatusCode(), messageWithCause("Failed writing to SFS", e));
|
||||
}
|
||||
catch (HttpClientErrorException e)
|
||||
{
|
||||
reply.setStatus(e.getStatusCode().value());
|
||||
reply.setErrorDetails(messageWithCause("Failed at writing the transformed file. ", e));
|
||||
|
||||
transformerDebug.logFailure(reply);
|
||||
logger.trace("Failed to save target file (HttpClientErrorException), sending " + reply, e);
|
||||
return false;
|
||||
throw new TransformException(e.getStatusCode(), messageWithCause("Failed writing to SFS", e));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
reply.setStatus(INTERNAL_SERVER_ERROR.value());
|
||||
reply.setErrorDetails(messageWithCause("Failed at writing the transformed file. ", e));
|
||||
|
||||
transformerDebug.logFailure(reply);
|
||||
logger.trace("Failed to save target file (Exception), sending " + reply, e);
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
deleteFile(targetFile);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.error("Failed to delete local temp target file. Error will be ignored ", e);
|
||||
throw new TransformException(INTERNAL_SERVER_ERROR, messageWithCause("Failed writing to SFS", e));
|
||||
}
|
||||
|
||||
reply.setTargetReference(targetRef.getEntry().getFileRef());
|
||||
reply.setStatus(CREATED.value());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the file with the specified sourceReference from Alfresco Shared File Store
|
||||
*
|
||||
* @param sourceReference reference to the file in Alfresco Shared File Store
|
||||
* @param sourceExtension default extension if the file in Alfresco Shared File Store has none
|
||||
* @return the file containing the source content for the transformation
|
||||
*/
|
||||
private File loadSourceFile(final String sourceReference, final String sourceExtension)
|
||||
{
|
||||
ResponseEntity<Resource> responseEntity = alfrescoSharedFileStoreClient.retrieveFile(sourceReference);
|
||||
|
||||
HttpHeaders headers = responseEntity.getHeaders();
|
||||
String filename = getFilenameFromContentDisposition(headers);
|
||||
|
||||
String extension = getFilenameExtension(filename) != null ? getFilenameExtension(filename) : sourceExtension;
|
||||
MediaType contentType = headers.getContentType();
|
||||
long size = headers.getContentLength();
|
||||
|
||||
final Resource body = responseEntity.getBody();
|
||||
if (body == null)
|
||||
{
|
||||
String message = "Source file with reference: " + sourceReference + " is null or empty. "
|
||||
+ "Transformation will fail and stop now as there is no content to be transformed.";
|
||||
logger.warn(message);
|
||||
throw new TransformException(BAD_REQUEST.value(), message);
|
||||
}
|
||||
final File file = createTempFile("source_", "." + extension);
|
||||
|
||||
logger.debug("Read source content {} length={} contentType={}",
|
||||
sourceReference, size, contentType);
|
||||
|
||||
save(body, file);
|
||||
LogEntry.setSource(filename, size);
|
||||
return file;
|
||||
}
|
||||
|
||||
private static String messageWithCause(final String prefix, Throwable e)
|
||||
@@ -554,7 +479,7 @@ public class TransformHandler
|
||||
sourceSizeInBytes, targetMimetype, transformOptions, null);
|
||||
if (transformerName == null)
|
||||
{
|
||||
throw new TransformException(BAD_REQUEST.value(), "No transforms were able to handle the request");
|
||||
throw new TransformException(BAD_REQUEST, "No transforms were able to handle the request");
|
||||
}
|
||||
return transformerName;
|
||||
}
|
||||
@@ -572,19 +497,35 @@ public class TransformHandler
|
||||
CustomTransformer customTransformer = customTransformersByName.get(transformName);
|
||||
if (customTransformer == null)
|
||||
{
|
||||
throw new TransformException(BAD_REQUEST.value(), "Custom Transformer "+customTransformer+" not found");
|
||||
throw new TransformException(INTERNAL_SERVER_ERROR, "Custom Transformer "+transformName+" not found");
|
||||
}
|
||||
return customTransformer;
|
||||
}
|
||||
|
||||
private void closeInputStreamWithoutException(InputStream inputStream) {
|
||||
try
|
||||
private void closeInputStreamWithoutException(InputStream inputStream)
|
||||
{
|
||||
if (inputStream != null)
|
||||
{
|
||||
inputStream.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
try
|
||||
{
|
||||
inputStream.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ResponseEntity<StreamingResponseBody> createResponseEntity(String targetMimetype,
|
||||
StreamingResponseBody body)
|
||||
{
|
||||
String extension = ExtensionService.getExtensionForMimetype(targetMimetype);
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentDisposition(
|
||||
ContentDisposition.attachment()
|
||||
.filename("transform."+ extension, StandardCharsets.UTF_8)
|
||||
.build());
|
||||
return ResponseEntity.ok().headers(headers).body(body);
|
||||
}
|
||||
}
|
||||
|
@@ -70,7 +70,7 @@ public class AlfrescoSharedFileStoreClient
|
||||
}
|
||||
catch (HttpClientErrorException e)
|
||||
{
|
||||
throw new TransformException(e.getStatusCode().value(), e.getMessage(), e);
|
||||
throw new TransformException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ public class AlfrescoSharedFileStoreClient
|
||||
}
|
||||
catch (HttpClientErrorException e)
|
||||
{
|
||||
throw new TransformException(e.getStatusCode().value(), e.getMessage(), e);
|
||||
throw new TransformException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* #%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.config;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.AsyncConfigurer;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@Configuration
|
||||
@EnableAsync
|
||||
public class SpringAsyncConfig implements AsyncConfigurer
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(SpringAsyncConfig.class);
|
||||
|
||||
@Value("${async-task-executor.core-pool-size:1}")
|
||||
int corePoolSize;
|
||||
|
||||
@Value("${async-task-executor.max-pool-size:"+Integer.MAX_VALUE+"}")
|
||||
int maxPoolSize;
|
||||
|
||||
@Value("${async-task-executor.keep-alive-seconds:60}")
|
||||
int keepAliveSeconds;
|
||||
|
||||
@Value("${async-task-executor.queue-capacity:"+Integer.MAX_VALUE+"}")
|
||||
int queueCapacity;
|
||||
|
||||
@Value("${async-task-executor.allow-core-thread-time-out:false}")
|
||||
boolean allowCoreThreadTimeOut;
|
||||
|
||||
@Value("${async-task-executor.prestart-all-core-threads:false}")
|
||||
boolean prestartAllCoreThreads;
|
||||
|
||||
@Override
|
||||
@Bean(name = "taskExecutor")
|
||||
public Executor getAsyncExecutor()
|
||||
{
|
||||
logger.debug("async-task-executor:");
|
||||
logger.debug(" corePoolSize="+corePoolSize);
|
||||
logger.debug(" max-pool-size: "+maxPoolSize);
|
||||
logger.debug(" keep-alive-seconds: "+keepAliveSeconds);
|
||||
logger.debug(" queue-capacity: "+queueCapacity);
|
||||
logger.debug(" allow-core-thread-time-out: "+allowCoreThreadTimeOut);
|
||||
logger.debug(" prestart-all-core-threads: "+prestartAllCoreThreads);
|
||||
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
executor.setCorePoolSize(corePoolSize);
|
||||
executor.setMaxPoolSize(maxPoolSize);
|
||||
executor.setKeepAliveSeconds(keepAliveSeconds);
|
||||
executor.setQueueCapacity(queueCapacity);
|
||||
executor.setAllowCoreThreadTimeOut(allowCoreThreadTimeOut);
|
||||
executor.setPrestartAllCoreThreads(prestartAllCoreThreads);
|
||||
return executor;
|
||||
}
|
||||
}
|
@@ -35,6 +35,7 @@ import org.alfresco.transform.registry.TransformServiceRegistry;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
@@ -42,7 +43,9 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM;
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackages = {"org.alfresco.transform"})
|
||||
@ComponentScan(
|
||||
basePackages = {"org.alfresco.transform"},
|
||||
excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = ".*Test.*"))
|
||||
public class WebApplicationConfig implements WebMvcConfigurer
|
||||
{
|
||||
@Override
|
||||
|
@@ -52,14 +52,12 @@ public abstract class AbstractCommandExecutor implements CommandExecutor
|
||||
|
||||
if (result.getExitValue() != 0 && result.getStdErr() != null && result.getStdErr().length() > 0)
|
||||
{
|
||||
throw new TransformException(BAD_REQUEST.value(),
|
||||
"Transformer exit code was not 0: \n" + result.getStdErr());
|
||||
throw new TransformException(BAD_REQUEST, "Transformer exit code was not 0: \n" + result.getStdErr());
|
||||
}
|
||||
|
||||
if (!targetFile.exists() || targetFile.length() == 0)
|
||||
{
|
||||
throw new TransformException(INTERNAL_SERVER_ERROR.value(),
|
||||
"Transformer failed to create an output file");
|
||||
throw new TransformException(INTERNAL_SERVER_ERROR, "Transformer failed to create an output file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -30,8 +30,11 @@ import org.alfresco.transform.base.logging.LogEntry;
|
||||
import org.alfresco.transform.common.ExtensionService;
|
||||
import org.alfresco.transform.common.TransformException;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.ContentDisposition;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.File;
|
||||
@@ -39,6 +42,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Arrays;
|
||||
|
||||
@@ -71,7 +75,7 @@ public class FileManager
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new TransformException(INSUFFICIENT_STORAGE.value(), "Failed to store the source file", e);
|
||||
throw new TransformException(INSUFFICIENT_STORAGE, "Failed to store the source file", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +94,7 @@ public class FileManager
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new TransformException(INSUFFICIENT_STORAGE.value(), "Failed to create the target file", e);
|
||||
throw new TransformException(INSUFFICIENT_STORAGE, "Failed to create the target file", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,8 +114,7 @@ public class FileManager
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new TransformException(INSUFFICIENT_STORAGE.value(),
|
||||
"Failed to store the source file", e);
|
||||
throw new TransformException(INSUFFICIENT_STORAGE, "Failed to store the source file", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +139,7 @@ public class FileManager
|
||||
InputStream inputStream;
|
||||
if (sourceMultipartFile == null)
|
||||
{
|
||||
throw new TransformException(BAD_REQUEST.value(), "Required request part 'file' is not present");
|
||||
throw new TransformException(BAD_REQUEST, "Required request part 'file' is not present");
|
||||
}
|
||||
try
|
||||
{
|
||||
@@ -144,7 +147,7 @@ public class FileManager
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new TransformException(BAD_REQUEST.value(), "Unable to read the sourceMultipartFile.", e);
|
||||
throw new TransformException(BAD_REQUEST, "Unable to read the sourceMultipartFile.", e);
|
||||
}
|
||||
return inputStream;
|
||||
}
|
||||
@@ -157,11 +160,11 @@ public class FileManager
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
throw new TransformException(BAD_REQUEST.value(), "Direct Access Url is invalid.", e);
|
||||
throw new TransformException(BAD_REQUEST, "Direct Access Url is invalid.", e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new TransformException(BAD_REQUEST.value(), "Direct Access Url not found.", e);
|
||||
throw new TransformException(BAD_REQUEST, "Direct Access Url not found.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,7 +176,7 @@ public class FileManager
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new TransformException(INTERNAL_SERVER_ERROR.value(), "Failed to copy targetFile to outputStream.", e);
|
||||
throw new TransformException(INTERNAL_SERVER_ERROR, "Failed to copy targetFile to outputStream.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -238,7 +238,7 @@ public class ProbeTestTransform
|
||||
|
||||
if (time > maxTime)
|
||||
{
|
||||
throw new TransformException(INTERNAL_SERVER_ERROR.value(),
|
||||
throw new TransformException(INTERNAL_SERVER_ERROR,
|
||||
getMessagePrefix(isLiveProbe) +
|
||||
message + " which is more than " + livenessPercent +
|
||||
"% slower than the normal value of " + normalTime + "ms");
|
||||
@@ -260,7 +260,7 @@ public class ProbeTestTransform
|
||||
sourceSizeInBytes, targetMimetype, transformOptions, null);
|
||||
if (transformerName == null)
|
||||
{
|
||||
throw new TransformException(BAD_REQUEST.value(), "No transforms were able to handle the request");
|
||||
throw new TransformException(BAD_REQUEST, "No transforms were able to handle the request");
|
||||
}
|
||||
return transformerName;
|
||||
}
|
||||
@@ -269,14 +269,14 @@ public class ProbeTestTransform
|
||||
{
|
||||
if (die.get())
|
||||
{
|
||||
throw new TransformException(TOO_MANY_REQUESTS.value(),
|
||||
throw new TransformException(TOO_MANY_REQUESTS,
|
||||
getMessagePrefix(isLiveProbe) + "Transformer requested to die. A transform took " +
|
||||
"longer than " + (maxTransformTime * 1000) + " seconds");
|
||||
}
|
||||
|
||||
if (maxTransformCount > 0 && transformCount.get() > maxTransformCount)
|
||||
{
|
||||
throw new TransformException(TOO_MANY_REQUESTS.value(),
|
||||
throw new TransformException(TOO_MANY_REQUESTS,
|
||||
getMessagePrefix(isLiveProbe) + "Transformer requested to die. It has performed " +
|
||||
"more than " + maxTransformCount + " transformations");
|
||||
}
|
||||
@@ -293,7 +293,7 @@ public class ProbeTestTransform
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new TransformException(INSUFFICIENT_STORAGE.value(),
|
||||
throw new TransformException(INSUFFICIENT_STORAGE,
|
||||
getMessagePrefix(isLiveProbe) + "Failed to store the source file", e);
|
||||
}
|
||||
long length = sourceFile.length();
|
||||
@@ -349,13 +349,13 @@ public class ProbeTestTransform
|
||||
String probeMessage = getProbeMessage(isLiveProbe);
|
||||
if (!targetFile.exists() || !targetFile.isFile())
|
||||
{
|
||||
throw new TransformException(INTERNAL_SERVER_ERROR.value(),
|
||||
throw new TransformException(INTERNAL_SERVER_ERROR,
|
||||
probeMessage + "Target File \"" + targetFile.getAbsolutePath() + "\" did not exist");
|
||||
}
|
||||
long length = targetFile.length();
|
||||
if (length < minExpectedLength || length > maxExpectedLength)
|
||||
{
|
||||
throw new TransformException(INTERNAL_SERVER_ERROR.value(),
|
||||
throw new TransformException(INTERNAL_SERVER_ERROR,
|
||||
probeMessage + "Target File \"" + targetFile.getAbsolutePath() +
|
||||
"\" was the wrong size (" + length + "). Needed to be between " +
|
||||
minExpectedLength + " and " + maxExpectedLength);
|
||||
|
@@ -59,3 +59,10 @@ management:
|
||||
container:
|
||||
name: ${HOSTNAME:t-engine}
|
||||
|
||||
async-task-executor:
|
||||
core-pool-size: 1
|
||||
max-pool-size: 2147483647
|
||||
keep-alive-seconds: 60
|
||||
queue-capacity: 2147483647
|
||||
allow-core-thread-time-out: false
|
||||
prestart-all-core-threads: false
|
@@ -6,27 +6,27 @@
|
||||
<table>
|
||||
<tr><td><div style="text-align:right">file</div></td><td><input type="file" name="file" /></td></tr>
|
||||
<tr><td><div style="text-align:right">Direct Url</div></td><td><input type="text" name="directAccessUrl"/></td></tr>
|
||||
<tr><td><div style="text-align:right">sourceMimetype</div></td><td><input type="text" name="sourceMimetype" value="image/jpeg" /></td>
|
||||
<tr><td><div style="text-align:right">sourceMimetype</div></td><td><input type="text" name="sourceMimetype" value="" /></td>
|
||||
<td><select name="_sourceMimetype">
|
||||
<option value="" >-- file extension --</option>
|
||||
<option value="image/jpeg" >jpeg</option>
|
||||
<option value="image/jpeg" >jpg</option>
|
||||
<option value="image/png">png</option>
|
||||
<option value="application/pdf">pdf</option>
|
||||
<option value="application/vnd.openxmlformats-officedocument.wordprocessingml.document">docx</option>
|
||||
<option value="application/vnd.openxmlformats-officedocument.presentationml.slideshow">ppsx</option>
|
||||
<option value="text/html">html</option>
|
||||
<option value="text/plain">text</option>
|
||||
<option value="text/plain">txt</option>
|
||||
</select></td></tr>
|
||||
<tr><td><div style="text-align:right">targetMimetype</div></td><td><input type="text" name="targetMimetype" value="image/png" /></td>
|
||||
<tr><td><div style="text-align:right">targetMimetype</div></td><td><input type="text" name="targetMimetype" value="" /></td>
|
||||
<td><select name="_targetMimetype">
|
||||
<option value="" >-- file extension --</option>
|
||||
<option value="image/jpeg" >jpeg</option>
|
||||
<option value="image/jpeg" >jpg</option>
|
||||
<option value="image/png">png</option>
|
||||
<option value="application/pdf">pdf</option>
|
||||
<option value="application/vnd.openxmlformats-officedocument.wordprocessingml.document">docx</option>
|
||||
<option value="application/vnd.openxmlformats-officedocument.presentationml.slideshow">ppsx</option>
|
||||
<option value="text/html">html</option>
|
||||
<option value="text/plain">text</option>
|
||||
<option value="text/plain">txt</option>
|
||||
</select></td></tr>
|
||||
<tr><td><select name="name0">
|
||||
<option value="sourceEncoding" >sourceEncoding</option>
|
||||
@@ -87,7 +87,7 @@
|
||||
<option value="includeContents">includeContents</option>
|
||||
<option value="notExtractBookmarksText">notExtractBookmarksText</option>
|
||||
<option value="pageLimit">pageLimit</option>
|
||||
</select></td><td><input type="text" name="value1" value="200" /></td></tr>
|
||||
</select></td><td><input type="text" name="value1" value="" /></td></tr>
|
||||
<tr><td><select id="name2">
|
||||
<option value="sourceEncoding">sourceEncoding</option>
|
||||
<option value="targetEncoding">targetEncoding</option>
|
||||
@@ -117,7 +117,7 @@
|
||||
<option value="includeContents">includeContents</option>
|
||||
<option value="notExtractBookmarksText">notExtractBookmarksText</option>
|
||||
<option value="pageLimit">pageLimit</option>
|
||||
</select></td><td><input type="text" name="value2" value="150" /></td></tr>
|
||||
</select></td><td><input type="text" name="value2" value="" /></td></tr>
|
||||
<tr><td><select name="name3">
|
||||
<option value="sourceEncoding">sourceEncoding</option>
|
||||
<option value="targetEncoding">targetEncoding</option>
|
||||
@@ -147,7 +147,7 @@
|
||||
<option value="includeContents">includeContents</option>
|
||||
<option value="notExtractBookmarksText">notExtractBookmarksText</option>
|
||||
<option value="pageLimit">pageLimit</option>
|
||||
</select></td><td><input type="text" name="value3" value="true" /></td></tr>
|
||||
</select></td><td><input type="text" name="value3" value="" /></td></tr>
|
||||
<tr><td><select name="name4">
|
||||
<option value="sourceEncoding">sourceEncoding</option>
|
||||
<option value="targetEncoding">targetEncoding</option>
|
||||
|
@@ -46,6 +46,7 @@ import static org.springframework.http.HttpStatus.OK;
|
||||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import java.io.File;
|
||||
@@ -80,12 +81,15 @@ import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.ResultActions;
|
||||
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
@@ -96,10 +100,11 @@ import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* Super class for testing controllers without a server. Includes tests for the Controller itself.
|
||||
* Super class for testing.
|
||||
*/
|
||||
//@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes={org.alfresco.transform.base.config.WebApplicationConfig.class})
|
||||
public abstract class AbstractTransformControllerTest
|
||||
@SpringBootTest(classes={org.alfresco.transform.base.Application.class})
|
||||
@AutoConfigureMockMvc
|
||||
public abstract class AbstractBaseTest
|
||||
{
|
||||
@TempDir // added as part of ATS-702 to allow test resources to be read from the imported jar files to prevent test resource duplication
|
||||
public File tempDir;
|
||||
@@ -132,7 +137,7 @@ public abstract class AbstractTransformControllerTest
|
||||
protected String expectedOptions;
|
||||
protected String expectedSourceSuffix;
|
||||
protected Long expectedTimeout = 0L;
|
||||
protected byte[] expectedSourceFileBytes;
|
||||
protected byte[] sourceFileBytes;
|
||||
|
||||
/**
|
||||
* The expected result. Taken resting target quick file's bytes.
|
||||
@@ -147,18 +152,12 @@ public abstract class AbstractTransformControllerTest
|
||||
String targetExtension, String sourceMimetype,
|
||||
boolean readTargetFileBytes) throws IOException;
|
||||
|
||||
protected TransformController getController()
|
||||
{
|
||||
return controller;
|
||||
}
|
||||
|
||||
protected ProbeTestTransform getProbeTestTransform()
|
||||
{
|
||||
return controller.probeTestTransform;
|
||||
}
|
||||
|
||||
protected abstract void updateTransformRequestWithSpecificOptions(
|
||||
TransformRequest transformRequest);
|
||||
protected abstract void updateTransformRequestWithSpecificOptions(TransformRequest transformRequest);
|
||||
|
||||
/**
|
||||
* This method ends up being the core of the mock.
|
||||
@@ -173,10 +172,14 @@ public abstract class AbstractTransformControllerTest
|
||||
public void generateTargetFileFromResourceFile(String actualTargetExtension, File testFile,
|
||||
File targetFile) throws IOException
|
||||
{
|
||||
if (testFile == null)
|
||||
{
|
||||
testFile = getTestFile("quick." + actualTargetExtension, false);
|
||||
}
|
||||
if (testFile != null)
|
||||
{
|
||||
try (var inputStream = new FileInputStream(testFile);
|
||||
var outputStream = new FileOutputStream(targetFile))
|
||||
var outputStream = new FileOutputStream(targetFile))
|
||||
{
|
||||
FileChannel source = inputStream.getChannel();
|
||||
FileChannel target = outputStream.getChannel();
|
||||
@@ -187,24 +190,6 @@ public abstract class AbstractTransformControllerTest
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
testFile = getTestFile("quick." + actualTargetExtension, false);
|
||||
if (testFile != null)
|
||||
{
|
||||
try (var inputStream = new FileInputStream(testFile);
|
||||
var outputStream = new FileOutputStream(targetFile))
|
||||
{
|
||||
FileChannel source = inputStream.getChannel();
|
||||
FileChannel target = outputStream.getChannel();
|
||||
target.transferFrom(source, 0, source.size());
|
||||
|
||||
} catch (Exception e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected byte[] readTestFile(String extension) throws IOException
|
||||
@@ -233,8 +218,7 @@ public abstract class AbstractTransformControllerTest
|
||||
return testFileUrl == null ? null : testFile;
|
||||
}
|
||||
|
||||
protected MockHttpServletRequestBuilder mockMvcRequest(String url, MockMultipartFile sourceFile,
|
||||
String... params)
|
||||
protected MockHttpServletRequestBuilder mockMvcRequest(String url, MockMultipartFile sourceFile, String... params)
|
||||
{
|
||||
if (sourceFile == null)
|
||||
{
|
||||
@@ -246,10 +230,9 @@ public abstract class AbstractTransformControllerTest
|
||||
}
|
||||
}
|
||||
|
||||
private MockHttpServletRequestBuilder mockMvcRequestWithoutMockMultipartFile(String url,
|
||||
String... params)
|
||||
private MockHttpServletRequestBuilder mockMvcRequestWithoutMockMultipartFile(String url, String... params)
|
||||
{
|
||||
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.multipart(ENDPOINT_TRANSFORM);
|
||||
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.multipart(url);
|
||||
|
||||
if (params.length % 2 != 0)
|
||||
{
|
||||
@@ -266,8 +249,7 @@ public abstract class AbstractTransformControllerTest
|
||||
private MockHttpServletRequestBuilder mockMvcRequestWithMockMultipartFile(String url, MockMultipartFile sourceFile,
|
||||
String... params)
|
||||
{
|
||||
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.multipart(ENDPOINT_TRANSFORM).file(
|
||||
sourceFile);
|
||||
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.multipart(ENDPOINT_TRANSFORM).file(sourceFile);
|
||||
|
||||
if (params.length % 2 != 0)
|
||||
{
|
||||
@@ -309,27 +291,13 @@ public abstract class AbstractTransformControllerTest
|
||||
public void simpleTransformTest() throws Exception
|
||||
{
|
||||
mockMvc.perform(
|
||||
mockMvcRequest(ENDPOINT_TRANSFORM, sourceFile, "targetExtension", targetExtension))
|
||||
.andExpect(status().is(OK.value()))
|
||||
mockMvcRequest(ENDPOINT_TRANSFORM, sourceFile))
|
||||
.andExpect(request().asyncStarted())
|
||||
.andDo(MvcResult::getAsyncResult)
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().bytes(expectedTargetFileBytes))
|
||||
.andExpect(header().string("Content-Disposition",
|
||||
"attachment; filename*= UTF-8''quick." + targetExtension));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelayTest() throws Exception
|
||||
{
|
||||
long start = System.currentTimeMillis();
|
||||
mockMvc.perform(mockMvcRequest(ENDPOINT_TRANSFORM, sourceFile, "targetExtension", targetExtension,
|
||||
"testDelay", "400"))
|
||||
.andExpect(status().is(OK.value()))
|
||||
.andExpect(content().bytes(expectedTargetFileBytes))
|
||||
.andExpect(header().string("Content-Disposition",
|
||||
"attachment; filename*= UTF-8''quick." + targetExtension));
|
||||
long ms = System.currentTimeMillis() - start;
|
||||
System.out.println("Transform incluing test delay was " + ms);
|
||||
assertTrue(ms >= 400, "Delay sending the result back was too small " + ms);
|
||||
assertTrue(ms <= 500,"Delay sending the result back was too big " + ms);
|
||||
"attachment; filename*=UTF-8''transform." + targetExtension));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -343,40 +311,42 @@ public abstract class AbstractTransformControllerTest
|
||||
// Looks dangerous but is okay as we only use the final filename
|
||||
public void dotDotSourceFilenameTest() throws Exception
|
||||
{
|
||||
sourceFile = new MockMultipartFile("file", "../quick." + sourceExtension, sourceMimetype,
|
||||
expectedSourceFileBytes);
|
||||
sourceFile = new MockMultipartFile("file", "../quick." + sourceExtension, sourceMimetype, sourceFileBytes);
|
||||
|
||||
mockMvc.perform(
|
||||
mockMvcRequest(ENDPOINT_TRANSFORM, sourceFile, "targetExtension", targetExtension))
|
||||
.andExpect(status().is(OK.value()))
|
||||
mockMvcRequest(ENDPOINT_TRANSFORM, sourceFile))
|
||||
.andExpect(request().asyncStarted())
|
||||
.andDo(MvcResult::getAsyncResult)
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().bytes(expectedTargetFileBytes))
|
||||
.andExpect(header().string("Content-Disposition",
|
||||
"attachment; filename*= UTF-8''quick." + targetExtension));
|
||||
"attachment; filename*=UTF-8''transform." + targetExtension));
|
||||
}
|
||||
|
||||
@Test
|
||||
// Is okay, as the target filename is built up from the whole source filename and the targetExtension
|
||||
public void noExtensionSourceFilenameTest() throws Exception
|
||||
{
|
||||
sourceFile = new MockMultipartFile("file", "../quick", sourceMimetype,
|
||||
expectedSourceFileBytes);
|
||||
sourceFile = new MockMultipartFile("file", "../quick", sourceMimetype, sourceFileBytes);
|
||||
|
||||
mockMvc.perform(
|
||||
mockMvcRequest(ENDPOINT_TRANSFORM, sourceFile, "targetExtension", targetExtension))
|
||||
.andExpect(status().is(OK.value()))
|
||||
mockMvcRequest(ENDPOINT_TRANSFORM, sourceFile))
|
||||
.andExpect(request().asyncStarted())
|
||||
.andDo(MvcResult::getAsyncResult)
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().bytes(expectedTargetFileBytes))
|
||||
.andExpect(header().string("Content-Disposition",
|
||||
"attachment; filename*= UTF-8''quick." + 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, expectedSourceFileBytes);
|
||||
sourceFile = new MockMultipartFile("file", "abc/", sourceMimetype, sourceFileBytes);
|
||||
|
||||
mockMvc.perform(
|
||||
mockMvcRequest(ENDPOINT_TRANSFORM, sourceFile, "targetExtension", targetExtension))
|
||||
mockMvcRequest(ENDPOINT_TRANSFORM, sourceFile))
|
||||
.andExpect(status().is(BAD_REQUEST.value()))
|
||||
.andExpect(status().reason(containsString("The source filename was not supplied")));
|
||||
}
|
||||
@@ -384,26 +354,17 @@ public abstract class AbstractTransformControllerTest
|
||||
@Test
|
||||
public void blankSourceFilenameTest() throws Exception
|
||||
{
|
||||
sourceFile = new MockMultipartFile("file", "", sourceMimetype, expectedSourceFileBytes);
|
||||
sourceFile = new MockMultipartFile("file", "", sourceMimetype, sourceFileBytes);
|
||||
|
||||
mockMvc.perform(
|
||||
mockMvcRequest(ENDPOINT_TRANSFORM, sourceFile, "targetExtension", targetExtension))
|
||||
mockMvcRequest(ENDPOINT_TRANSFORM, sourceFile))
|
||||
.andExpect(status().is(BAD_REQUEST.value()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noTargetExtensionTest() throws Exception
|
||||
{
|
||||
mockMvc.perform(mockMvcRequest(ENDPOINT_TRANSFORM, sourceFile))
|
||||
.andExpect(status().is(BAD_REQUEST.value()))
|
||||
.andExpect(status().reason(
|
||||
containsString("Request parameter 'targetExtension' is missing")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void calculateMaxTime() throws Exception
|
||||
{
|
||||
ProbeTestTransform probeTestTransform = getController().probeTestTransform;
|
||||
ProbeTestTransform probeTestTransform = controller.probeTestTransform;
|
||||
probeTestTransform.setLivenessPercent(110);
|
||||
|
||||
long[][] values = new long[][]{
|
||||
@@ -479,7 +440,9 @@ public abstract class AbstractTransformControllerTest
|
||||
|
||||
String response = mockMvc
|
||||
.perform(MockMvcRequestBuilders.get(ENDPOINT_TRANSFORM_CONFIG_LATEST))
|
||||
.andExpect(status().is(OK.value()))
|
||||
.andExpect(request().asyncStarted())
|
||||
.andDo(MvcResult::getAsyncResult)
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(header().string(CONTENT_TYPE, APPLICATION_JSON_VALUE))
|
||||
.andReturn().getResponse().getContentAsString();
|
||||
|
||||
@@ -500,7 +463,9 @@ public abstract class AbstractTransformControllerTest
|
||||
|
||||
String response = mockMvc
|
||||
.perform(MockMvcRequestBuilders.get(ENDPOINT_TRANSFORM_CONFIG))
|
||||
.andExpect(status().is(OK.value()))
|
||||
.andExpect(request().asyncStarted())
|
||||
.andDo(MvcResult::getAsyncResult)
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(header().string(CONTENT_TYPE, APPLICATION_JSON_VALUE))
|
||||
.andReturn().getResponse().getContentAsString();
|
||||
|
||||
@@ -518,7 +483,9 @@ public abstract class AbstractTransformControllerTest
|
||||
|
||||
String response = mockMvc
|
||||
.perform(MockMvcRequestBuilders.get(ENDPOINT_TRANSFORM_CONFIG))
|
||||
.andExpect(status().is(OK.value()))
|
||||
.andExpect(request().asyncStarted())
|
||||
.andDo(MvcResult::getAsyncResult)
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(header().string(CONTENT_TYPE, APPLICATION_JSON_VALUE))
|
||||
.andReturn().getResponse().getContentAsString();
|
||||
|
||||
@@ -545,7 +512,9 @@ public abstract class AbstractTransformControllerTest
|
||||
|
||||
String response = mockMvc
|
||||
.perform(MockMvcRequestBuilders.get(ENDPOINT_TRANSFORM_CONFIG))
|
||||
.andExpect(status().is(OK.value()))
|
||||
.andExpect(request().asyncStarted())
|
||||
.andDo(MvcResult::getAsyncResult)
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(header().string(CONTENT_TYPE, APPLICATION_JSON_VALUE))
|
||||
.andReturn().getResponse().getContentAsString();
|
||||
|
||||
@@ -568,7 +537,9 @@ public abstract class AbstractTransformControllerTest
|
||||
|
||||
String response = mockMvc
|
||||
.perform(MockMvcRequestBuilders.get(ENDPOINT_TRANSFORM_CONFIG))
|
||||
.andExpect(status().is(OK.value()))
|
||||
.andExpect(request().asyncStarted())
|
||||
.andDo(MvcResult::getAsyncResult)
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(header().string(CONTENT_TYPE, APPLICATION_JSON_VALUE))
|
||||
.andReturn().getResponse().getContentAsString();
|
||||
|
@@ -44,8 +44,7 @@ import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
|
||||
/**
|
||||
* Super class for testing controllers with a server. Includes tests for the Controller itself.
|
||||
* Note: Currently uses json rather than HTML as json is returned by this spring boot test harness.
|
||||
* Super class with a server test harness, which talks to the TransformController using http.
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes={org.alfresco.transform.base.Application.class})
|
||||
public abstract class AbstractHttpRequestTest
|
||||
|
@@ -44,7 +44,6 @@ public class EngineClient
|
||||
{
|
||||
final HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MULTIPART_FORM_DATA);
|
||||
//headers.setAccept(ImmutableList.of(MULTIPART_FORM_DATA));
|
||||
|
||||
final MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
|
||||
body.add("file", new ClassPathResource(sourceFile));
|
||||
|
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Transform Core
|
||||
* %%
|
||||
* Copyright (C) 2005 - 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.components.TestTransformEngineTwoTransformers;
|
||||
import org.alfresco.transform.base.components.TestTransformerPdf2Png;
|
||||
import org.alfresco.transform.base.components.TestTransformerTxT2Pdf;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static org.alfresco.transform.common.Mimetype.MIMETYPE_IMAGE_PNG;
|
||||
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.RequestParamMap.ENDPOINT_TRANSFORM;
|
||||
import static org.alfresco.transform.common.RequestParamMap.SOURCE_MIMETYPE;
|
||||
import static org.alfresco.transform.common.RequestParamMap.TARGET_MIMETYPE;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* Testing base t-engine TransformController functionality.
|
||||
*/
|
||||
@AutoConfigureMockMvc
|
||||
@SpringBootTest(classes={org.alfresco.transform.base.Application.class})
|
||||
@ContextConfiguration(classes = {
|
||||
TestTransformerTxT2Pdf.class,
|
||||
TestTransformerPdf2Png.class,
|
||||
TestTransformEngineTwoTransformers.class})
|
||||
public class TransformControllerTestWithBasicConfig
|
||||
{
|
||||
@Autowired
|
||||
protected MockMvc mockMvc;
|
||||
|
||||
private void assertGoodTransform(String originalValue, String expectedValue, String sourceMimetype, String targetMimetype,
|
||||
String expectedTargetExtension) throws Exception
|
||||
{
|
||||
mockMvc.perform(
|
||||
MockMvcRequestBuilders.multipart(ENDPOINT_TRANSFORM)
|
||||
.file(new MockMultipartFile("file", null, sourceMimetype,
|
||||
originalValue.getBytes(StandardCharsets.UTF_8)))
|
||||
.param(SOURCE_MIMETYPE, sourceMimetype)
|
||||
.param(TARGET_MIMETYPE, targetMimetype))
|
||||
.andExpect(request().asyncStarted())
|
||||
.andDo(MvcResult::getAsyncResult)
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(header().string("Content-Disposition",
|
||||
"attachment; filename*=UTF-8''transform." + expectedTargetExtension))
|
||||
.andExpect(content().string(expectedValue));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleStepTransform() throws Exception
|
||||
{
|
||||
assertGoodTransform("Start", "Start -> TxT2Pdf()",
|
||||
MIMETYPE_TEXT_PLAIN, MIMETYPE_PDF, "pdf");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pipelineTransform() throws Exception
|
||||
{
|
||||
assertGoodTransform("Start", "Start -> TxT2Pdf() -> Pdf2Png()",
|
||||
MIMETYPE_TEXT_PLAIN, MIMETYPE_IMAGE_PNG, "png");
|
||||
}
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Transform Core
|
||||
* %%
|
||||
* Copyright (C) 2005 - 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.components;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.alfresco.transform.base.TransformEngine;
|
||||
import org.alfresco.transform.base.probes.ProbeTestTransform;
|
||||
import org.alfresco.transform.config.SupportedSourceAndTarget;
|
||||
import org.alfresco.transform.config.TransformConfig;
|
||||
import org.alfresco.transform.config.TransformOptionValue;
|
||||
import org.alfresco.transform.config.Transformer;
|
||||
import org.springframework.boot.test.context.TestComponent;
|
||||
|
||||
import static org.alfresco.transform.common.Mimetype.MIMETYPE_HTML;
|
||||
import static org.alfresco.transform.common.Mimetype.MIMETYPE_IMAGE_PNG;
|
||||
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.RequestParamMap.SOURCE_ENCODING;
|
||||
|
||||
/**
|
||||
* Subclass MUST be named TestTransformEngine\<something>.
|
||||
*/
|
||||
@TestComponent
|
||||
public abstract class AbstractTestTransformEngine implements TransformEngine
|
||||
{
|
||||
@Override public String getTransformEngineName()
|
||||
{
|
||||
String simpleClassName = getClass().getSimpleName();
|
||||
return simpleClassName.substring("TestTransformEngine".length());
|
||||
}
|
||||
|
||||
@Override public String getStartupMessage()
|
||||
{
|
||||
return "Startup";
|
||||
}
|
||||
|
||||
@Override public TransformConfig getTransformConfig()
|
||||
{
|
||||
String docOptions = "docOptions";
|
||||
String imageOptions = "imageOptions";
|
||||
return TransformConfig.builder()
|
||||
// .withTransformOptions(ImmutableMap.of(
|
||||
// docOptions, ImmutableSet.of(
|
||||
// new TransformOptionValue(false, "page")),
|
||||
// imageOptions, ImmutableSet.of(
|
||||
// new TransformOptionValue(false, "width"),
|
||||
// new TransformOptionValue(false, "height"))))
|
||||
.withTransformers(ImmutableList.of(
|
||||
Transformer.builder()
|
||||
.withTransformerName("TxT2Pdf")
|
||||
.withSupportedSourceAndTargetList(ImmutableSet.of(
|
||||
SupportedSourceAndTarget.builder()
|
||||
.withSourceMediaType(MIMETYPE_TEXT_PLAIN)
|
||||
.withTargetMediaType(MIMETYPE_PDF)
|
||||
.build()))
|
||||
// .withTransformOptions(ImmutableSet.of(docOptions))
|
||||
.build(),
|
||||
Transformer.builder()
|
||||
.withTransformerName("Pdf2Png")
|
||||
.withSupportedSourceAndTargetList(ImmutableSet.of(
|
||||
SupportedSourceAndTarget.builder()
|
||||
.withSourceMediaType(MIMETYPE_PDF)
|
||||
.withTargetMediaType(MIMETYPE_IMAGE_PNG)
|
||||
.build()))
|
||||
// .withTransformOptions(ImmutableSet.of(imageOptions))
|
||||
.build()))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override public ProbeTestTransform getLivenessAndReadinessProbeTestTransform()
|
||||
{
|
||||
return new ProbeTestTransform("quick.html", "quick.txt",
|
||||
MIMETYPE_HTML, MIMETYPE_TEXT_PLAIN, ImmutableMap.of(SOURCE_ENCODING, "UTF-8"),
|
||||
119, 30, 150, 1024, 60 * 2 + 1, 60 * 2);
|
||||
}
|
||||
}
|
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Transform Core
|
||||
* %%
|
||||
* Copyright (C) 2005 - 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.components;
|
||||
|
||||
import org.alfresco.transform.base.CustomTransformer;
|
||||
import org.alfresco.transform.base.TransformManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.test.context.TestComponent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Subclass MUST be named TestTransformer\<something>. Appends the name of the CustomTransformer and any t-options
|
||||
* to the output. The output is always a String regardless of the stated mimetypes.
|
||||
*/
|
||||
@TestComponent
|
||||
public abstract class AbstractTestTransformer implements CustomTransformer
|
||||
{
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@Override
|
||||
public String getTransformerName()
|
||||
{
|
||||
String simpleClassName = getClass().getSimpleName();
|
||||
return simpleClassName.substring("TestTransformer".length());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transform(String sourceMimetype, InputStream inputStream, String targetMimetype,
|
||||
OutputStream outputStream, Map<String, String> transformOptions, TransformManager transformManager)
|
||||
throws Exception
|
||||
{
|
||||
String oldValue = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
|
||||
String newValue = new StringBuilder(oldValue)
|
||||
.append(" -> ")
|
||||
.append(getTransformerName())
|
||||
.append("(")
|
||||
.append(transformOptions.entrySet()
|
||||
.stream()
|
||||
.map(e -> e.getKey() + '=' + e.getValue())
|
||||
.collect(Collectors.joining(", ")))
|
||||
.append(')')
|
||||
.toString();
|
||||
logger.info(newValue);
|
||||
byte[] bytes = newValue.getBytes(StandardCharsets.UTF_8);
|
||||
outputStream.write(bytes, 0, bytes.length);
|
||||
}
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Transform Core
|
||||
* %%
|
||||
* Copyright (C) 2005 - 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.components;
|
||||
|
||||
public class TestTransformEngineTwoTransformers extends AbstractTestTransformEngine
|
||||
{
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Transform Core
|
||||
* %%
|
||||
* Copyright (C) 2005 - 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.components;
|
||||
|
||||
public class TestTransformerPdf2Png extends AbstractTestTransformer
|
||||
{
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Transform Core
|
||||
* %%
|
||||
* Copyright (C) 2005 - 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.components;
|
||||
|
||||
public class TestTransformerTxT2Pdf extends AbstractTestTransformer
|
||||
{
|
||||
}
|
17
engines/base/src/test/resources/quick.html
Normal file
17
engines/base/src/test/resources/quick.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
|
||||
<title>The quick brown fox jumps over the lazy dog</title>
|
||||
<meta name="author" content="Nevin Nollop">
|
||||
<meta name="keywords" content="Pangram, fox, dog">
|
||||
<meta name="description" content="Gym class featuring a brown fox and lazy dog">
|
||||
</head>
|
||||
|
||||
<body lang=EN-US>
|
||||
|
||||
The quick brown fox jumps over the lazy dog
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
18
engines/base/src/test/resources/quick2.txt
Normal file
18
engines/base/src/test/resources/quick2.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The quick brown fox jumps over the lazy dog
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The quick brown fox jumps over the lazy dog
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user