Save point: [skip ci]

* HttpStatus
This commit is contained in:
alandavis
2022-07-15 18:34:23 +01:00
parent ea22605eba
commit e5728d5d44
55 changed files with 940 additions and 575 deletions

View File

@@ -188,7 +188,7 @@ public abstract class AbstractTransformerController implements TransformControll
{
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");
}
sourceFile = createSourceFile(request, sourceMultipartFile);
sourceFilename = sourceMultipartFile.getOriginalFilename();
@@ -236,11 +236,11 @@ public abstract class AbstractTransformerController implements TransformControll
}
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);
}
return sourceFile;
@@ -312,7 +312,7 @@ public abstract class AbstractTransformerController implements TransformControll
}
catch (TransformException e)
{
reply.setStatus(e.getStatusCode());
reply.setStatus(e.getStatusCode().value());
reply.setErrorDetails(messageWithCause("Failed at reading the source file", e));
transformerDebug.logFailure(reply);
@@ -356,7 +356,7 @@ public abstract class AbstractTransformerController implements TransformControll
}
catch (TransformException e)
{
reply.setStatus(e.getStatusCode());
reply.setStatus(e.getStatusCode().value());
reply.setErrorDetails(messageWithCause("Failed at processing transformation", e));
transformerDebug.logFailure(reply);
@@ -381,7 +381,7 @@ public abstract class AbstractTransformerController implements TransformControll
}
catch (TransformException e)
{
reply.setStatus(e.getStatusCode());
reply.setStatus(e.getStatusCode().value());
reply.setErrorDetails(messageWithCause("Failed at writing the transformed file", e));
transformerDebug.logFailure(reply);
@@ -481,7 +481,7 @@ public abstract class AbstractTransformerController implements TransformControll
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);
throw new TransformException(BAD_REQUEST, message);
}
final File file = createTempFile("source_", "." + extension);
@@ -542,8 +542,7 @@ public abstract class AbstractTransformerController implements TransformControll
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;
}

View File

@@ -116,7 +116,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;
}
@@ -155,23 +155,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());
}
}

View File

@@ -210,7 +210,7 @@ public interface TransformController
TransformException e) throws IOException
{
final String message = e.getMessage();
final int statusCode = e.getStatusCode();
final int statusCode = e.getStatusCode().value();
logger.error(message, e);

View File

@@ -92,8 +92,7 @@ public class TransformRegistryImpl extends AbstractTransformRegistry
}
catch (IOException e)
{
throw new TransformException(INTERNAL_SERVER_ERROR.value(),
"Could not read " + locationFromProperty, e);
throw new TransformException(INTERNAL_SERVER_ERROR, "Could not read " + locationFromProperty, e);
}
}

View File

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

View File

@@ -55,14 +55,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");
}
}
@@ -74,14 +72,14 @@ public abstract class AbstractCommandExecutor implements CommandExecutor
final ExecutionResult result = checkCommand.execute();
if (result.getExitValue() != 0 && result.getStdErr() != null && result.getStdErr().length() > 0)
{
throw new TransformException(INTERNAL_SERVER_ERROR.value(),
throw new TransformException(INTERNAL_SERVER_ERROR,
"Transformer version check exit code was not 0: \n" + result);
}
final String version = result.getStdOut().trim();
if (version.isEmpty())
{
throw new TransformException(INTERNAL_SERVER_ERROR.value(),
throw new TransformException(INTERNAL_SERVER_ERROR,
"Transformer version check failed to create any output");
}
return version;

View File

@@ -82,20 +82,20 @@ public interface Transformer
}
catch (IllegalArgumentException e)
{
throw new TransformException(BAD_REQUEST.value(), getMessage(e), e);
throw new TransformException(BAD_REQUEST, getMessage(e), e);
}
catch (Exception e)
{
throw new TransformException(INTERNAL_SERVER_ERROR.value(), getMessage(e), e);
throw new TransformException(INTERNAL_SERVER_ERROR, getMessage(e), e);
}
if (!targetFile.exists())
{
throw new TransformException(INTERNAL_SERVER_ERROR.value(),
throw new TransformException(INTERNAL_SERVER_ERROR,
"Transformer failed to create an output file. Target file does not exist.");
}
if (sourceFile.length() > 0 && targetFile.length() == 0)
{
throw new TransformException(INTERNAL_SERVER_ERROR.value(),
throw new TransformException(INTERNAL_SERVER_ERROR,
"Transformer failed to create an output file. Target file is empty but source file was not empty.");
}
}

View File

@@ -47,6 +47,7 @@ import org.alfresco.transformer.logging.LogEntry;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.UriUtils;
@@ -104,9 +105,8 @@ public class FileManager
if (filename == null || filename.isEmpty())
{
String sourceOrTarget = source ? "source" : "target";
int statusCode = source ? BAD_REQUEST.value() : INTERNAL_SERVER_ERROR.value();
throw new TransformException(statusCode,
"The " + sourceOrTarget + " filename was not supplied");
HttpStatus statusCode = source ? BAD_REQUEST : INTERNAL_SERVER_ERROR;
throw new TransformException(statusCode, "The " + sourceOrTarget + " filename was not supplied");
}
return filename;
}
@@ -120,8 +120,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);
}
}
@@ -133,8 +132,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);
}
}
@@ -149,13 +147,13 @@ public class FileManager
}
else
{
throw new TransformException(INTERNAL_SERVER_ERROR.value(),
throw new TransformException(INTERNAL_SERVER_ERROR,
"Could not read the target file: " + file.getPath());
}
}
catch (MalformedURLException e)
{
throw new TransformException(INTERNAL_SERVER_ERROR.value(),
throw new TransformException(INTERNAL_SERVER_ERROR,
"The target filename was malformed: " + file.getPath(), e);
}
}
@@ -238,7 +236,7 @@ public class FileManager
Resource targetResource = load(targetFile);
targetFilename = UriUtils.encodePath(getFilename(targetFilename), "UTF-8");
return ResponseEntity.ok().header(CONTENT_DISPOSITION,
"attachment; filename*= UTF-8''" + targetFilename).body(targetResource);
"attachment; filename*=UTF-8''" + targetFilename).body(targetResource);
}
/**

View File

@@ -229,7 +229,7 @@ public abstract 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");
@@ -247,14 +247,14 @@ public abstract 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");
}
@@ -271,7 +271,7 @@ public abstract 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();
@@ -329,13 +329,13 @@ public abstract 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);

View File

@@ -26,41 +26,10 @@
*/
package org.alfresco.transformer;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static org.alfresco.transform.common.RequestParamMap.DIRECT_ACCESS_URL;
import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM;
import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM_CONFIG_LATEST;
import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM_CONFIG;
import static org.hamcrest.Matchers.containsString;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.springframework.http.HttpHeaders.ACCEPT;
import static org.springframework.http.HttpHeaders.CONTENT_TYPE;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
import static org.springframework.http.HttpStatus.OK;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import org.alfresco.transform.client.model.InternalContext;
import org.alfresco.transform.client.model.TransformReply;
import org.alfresco.transform.client.model.TransformRequest;
@@ -70,8 +39,8 @@ import org.alfresco.transform.config.TransformOption;
import org.alfresco.transform.config.TransformOptionGroup;
import org.alfresco.transform.config.TransformOptionValue;
import org.alfresco.transform.config.Transformer;
import org.alfresco.transform.registry.TransformServiceRegistry;
import org.alfresco.transform.messages.TransformStack;
import org.alfresco.transform.registry.TransformServiceRegistry;
import org.alfresco.transformer.clients.AlfrescoSharedFileStoreClient;
import org.alfresco.transformer.model.FileRefEntity;
import org.alfresco.transformer.model.FileRefResponse;
@@ -90,10 +59,40 @@ import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static org.alfresco.transform.common.RequestParamMap.DIRECT_ACCESS_URL;
import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM;
import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM_CONFIG;
import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM_CONFIG_LATEST;
import static org.hamcrest.Matchers.containsString;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.springframework.http.HttpHeaders.ACCEPT;
import static org.springframework.http.HttpHeaders.CONTENT_TYPE;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
import static org.springframework.http.HttpStatus.OK;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Super class for testing controllers without a server. Includes tests for the AbstractTransformerController itself.

View File

@@ -29,7 +29,7 @@ package org.alfresco.transform.aio;
import org.alfresco.transform.base.AbstractHttpRequestTest;
/**
* Tests All-In-One with a server test harness that talks to the TransformController using http.
* Tests All-In-One using http and a server test harness.
*/
public class AIOHttpRequestTest extends AbstractHttpRequestTest
{

View File

@@ -27,27 +27,21 @@
package org.alfresco.transform.aio;
import org.alfresco.transform.base.TransformRegistryImpl;
import org.alfresco.transform.config.Transformer;
import org.alfresco.transform.imagemagick.ImageMagickControllerTest;
import org.alfresco.transform.registry.AbstractTransformRegistry;
import org.alfresco.transform.imagemagick.ImageMagickTest;
import org.junit.jupiter.api.BeforeEach;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import java.io.IOException;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Test the AIOController ImageMagick transforms without a server.
* Super class includes tests for the TransformController.
* Test ImageMagick functionality in All-In-One.
*/
@WebMvcTest()
public class AIOControllerImageMagickTest extends ImageMagickControllerTest
public class AIOImageMagickTest extends ImageMagickTest
{
@Autowired TransformRegistryImpl transformRegistry;

View File

@@ -26,22 +26,16 @@
*/
package org.alfresco.transform.aio;
import org.alfresco.transform.libreoffice.LibreOfficeControllerTest;
import org.alfresco.transform.libreoffice.LibreOfficeTest;
//import org.alfresco.transform.libreoffice.transformers.LibreOfficeTransformer;
import org.alfresco.transform.registry.AbstractTransformRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import java.util.Map;
@WebMvcTest()
/**
* Test the AIOController without a server.
* Super class includes tests for the LibreOfficeController and TransformController.
* Test LibreOffice functionality in All-In-One.
*/
public class AIOControllerLibreOfficeTest extends LibreOfficeControllerTest
public class AIOLibreOfficeTest extends LibreOfficeTest
{
// @Autowired AbstractTransformRegistry transformRegistry;
//

View File

@@ -28,13 +28,13 @@ package org.alfresco.transform.aio;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.alfresco.transform.misc.MiscControllerTest;
import org.junit.jupiter.api.Test;
import org.alfresco.transform.misc.MiscTest;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.context.annotation.Import;
@WebMvcTest()
public class AIOControllerMiscTest extends MiscControllerTest
/**
* Test Misc functionality in All-In-One.
*/
public class AIOMiscTest extends MiscTest
{
// @Test
// @Override

View File

@@ -26,22 +26,17 @@
*/
package org.alfresco.transform.aio;
import org.alfresco.transform.pdfrenderer.AlfrescoPdfRendererControllerTest;
import org.alfresco.transform.pdfrenderer.PdfRendererTest;
import org.alfresco.transform.registry.AbstractTransformRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import java.util.Map;
@WebMvcTest()
/**
* Test the AIOController PDF Renderer transforms without a server.
* Super class includes tests for the TransformController.
* Test PdfRenderer functionality in All-In-One.
*/
public class AIOControllerPdfRendererTest extends AlfrescoPdfRendererControllerTest
public class AIOPdfRendererTest extends PdfRendererTest
{
@Autowired AbstractTransformRegistry transformRegistry;

View File

@@ -26,7 +26,7 @@
*/
package org.alfresco.transform.aio;
import org.alfresco.transform.base.AbstractTransformControllerTest;
import org.alfresco.transform.base.AbstractBaseTest;
import org.alfresco.transform.client.model.TransformRequest;
import org.alfresco.transform.config.TransformConfig;
import org.junit.jupiter.api.Test;
@@ -41,8 +41,10 @@ import static org.alfresco.transform.common.RequestParamMap.CONFIG_VERSION_LATES
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
@WebMvcTest()
public class AIOControllerTest extends AbstractTransformControllerTest
/**
* Test All-In-One.
*/
public class AIOTest extends AbstractBaseTest
{
@Value("${transform.core.version}")
private String coreVersion;

View File

@@ -26,16 +26,13 @@
*/
package org.alfresco.transform.aio;
import org.alfresco.transform.tika.TikaControllerTest;
import org.junit.jupiter.api.Test;
import org.alfresco.transform.tika.TikaTest;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
@WebMvcTest()
/**
* Test the AIOController Tika transforms without a server.
* Super class includes tests for the TransformController.
* Test Tika functionality in All-In-One.
*/
public class AIOControllerTikaTest extends TikaControllerTest
public class AIOTikaTest extends TikaTest
{
// @Test
// @Override

View File

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

View File

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

View File

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

View File

@@ -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,8 +175,16 @@ 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)
{
return createResponseEntity(targetMimetype, os ->
{
TransformManagerImpl transformManager = null;
String reference = "e" + httpRequestCount.getAndIncrement();
try
{
if (logger.isDebugEnabled())
{
@@ -189,28 +194,25 @@ public class TransformHandler
probeTestTransform.incrementTransformerCount();
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.
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);
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()
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,55 +222,54 @@ 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);
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);
TransformManagerImpl transformManager = TransformManagerImpl.builder()
try (OutputStreamLengthRecorder outputStream = new OutputStreamLengthRecorder(new BufferedOutputStream(
new FileOutputStream(targetFile))))
{
transformManager = TransformManagerImpl.builder()
.withSourceMimetype(sourceMimetype)
.withTargetMimetype(targetMimetype)
.withInputStream(inputStream)
@@ -276,20 +277,28 @@ public class TransformHandler
.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()));
saveTargetFileInSharedFileStore(targetFile, reply);
}
transformManager.deleteSourceFileIfExists();
transformManager.deleteTargetFileIfExists();
}
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);
@@ -297,50 +306,38 @@ public class TransformHandler
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));
}
private ResponseEntity<TransformReply> createFailedResponseEntity(TransformReply reply, Exception e,
int status) {
reply.setStatus(status);
reply.setErrorDetails(messageWithCause("Transform failed", e));
transformerDebug.logFailure(reply);
logger.trace("Failed to perform transform (TransformException), sending " + reply, e);
logger.trace("Transform failed. 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()));
}
}
finally
private void deleteTmpFiles(TransformManagerImpl transformManager)
{
closeInputStreamWithoutException(inputStream);
if (transformManager != null)
{
transformManager.deleteSourceFileIfExists();
transformManager.deleteTargetFileIfExists();
}
}
private boolean isTransformRequestValid(TransformRequest request, TransformReply reply)
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,12 +497,15 @@ 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) {
private void closeInputStreamWithoutException(InputStream inputStream)
{
if (inputStream != null)
{
try
{
inputStream.close();
@@ -587,4 +515,17 @@ public class TransformHandler
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);
}
}

View File

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

View File

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

View File

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

View File

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

View 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);
}
}

View File

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

View File

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

View File

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

View File

@@ -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,23 +172,10 @@ public abstract class AbstractTransformControllerTest
public void generateTargetFileFromResourceFile(String actualTargetExtension, File testFile,
File targetFile) throws IOException
{
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;
}
}
else
if (testFile == null)
{
testFile = getTestFile("quick." + actualTargetExtension, false);
}
if (testFile != null)
{
try (var inputStream = new FileInputStream(testFile);
@@ -205,7 +191,6 @@ public abstract class AbstractTransformControllerTest
}
}
}
}
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();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

@@ -0,0 +1,18 @@
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog

View File

@@ -254,7 +254,7 @@ public final class ImageMagickOptionsBuilder
}
else if (!GRAVITY_VALUES.contains(cropGravity))
{
throw new TransformException(BAD_REQUEST.value(), "Invalid cropGravity value");
throw new TransformException(BAD_REQUEST, "Invalid cropGravity value");
}
}

View File

@@ -29,7 +29,7 @@ package org.alfresco.transform.imagemagick;
import org.alfresco.transform.base.AbstractHttpRequestTest;
/**
* Tests ImageMagick with a server test harness that talks to the TransformController using http.
* Tests ImageMagick using http and a server test harness.
*/
public class ImageMagickHttpRequestTest extends AbstractHttpRequestTest
{

View File

@@ -44,6 +44,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import static org.springframework.http.MediaType.IMAGE_PNG_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 static org.springframework.util.StringUtils.getFilenameExtension;
@@ -59,8 +60,7 @@ import javax.annotation.PostConstruct;
import org.alfresco.transform.client.model.TransformReply;
import org.alfresco.transform.client.model.TransformRequest;
import org.alfresco.transform.imagemagick.transformers.ImageMagickTransformer;
import org.alfresco.transform.base.TransformController;
import org.alfresco.transform.base.AbstractTransformControllerTest;
import org.alfresco.transform.base.AbstractBaseTest;
import org.alfresco.transform.base.executors.RuntimeExec;
import org.alfresco.transform.base.executors.RuntimeExec.ExecutionResult;
import org.alfresco.transform.base.model.FileRefEntity;
@@ -71,23 +71,20 @@ import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.Mock;
import org.mockito.stubbing.Answer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
/**
* Test the ImageMagickController without a server.
* Super class includes tests for the TransformController.
* Test ImageMagick.
*/
@WebMvcTest()
public class ImageMagickControllerTest extends AbstractTransformControllerTest
public class ImageMagickTest extends AbstractBaseTest
{
private static final String ENGINE_CONFIG_NAME = "imagemagick_engine_config.json";
@@ -153,10 +150,9 @@ public class ImageMagickControllerTest extends AbstractTransformControllerTest
expectedOptions = null;
expectedSourceSuffix = null;
expectedSourceFileBytes = readTestFile(sourceExtension);
sourceFileBytes = readTestFile(sourceExtension);
expectedTargetFileBytes = readTargetFileBytes ? readTestFile(targetExtension) : null;
sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype,
expectedSourceFileBytes);
sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype, sourceFileBytes);
when(mockTransformCommand.execute(any(), anyLong())).thenAnswer(
(Answer<RuntimeExec.ExecutionResult>) invocation -> {
@@ -202,7 +198,7 @@ public class ImageMagickControllerTest extends AbstractTransformControllerTest
// Check the supplied source file has not been changed.
byte[] actualSourceFileBytes = Files.readAllBytes(new File(actualSource).toPath());
assertTrue(Arrays.equals(expectedSourceFileBytes, actualSourceFileBytes),
assertTrue(Arrays.equals(sourceFileBytes, actualSourceFileBytes),
"Source file is not the same");
return mockExecutionResult;
@@ -226,10 +222,12 @@ public class ImageMagickControllerTest extends AbstractTransformControllerTest
.param("targetMimetype", targetMimetype)
.param("sourceMimetype", sourceMimetype)
.param("cropGravity", value))
.andExpect(status().is(OK.value()))
.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
@@ -278,10 +276,12 @@ public class ImageMagickControllerTest extends AbstractTransformControllerTest
.param("resizePercentage", "true")
.param("allowEnlargement", "true")
.param("maintainAspectRatio", "false"))
.andExpect(status().is(OK.value()))
.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
@@ -316,10 +316,12 @@ public class ImageMagickControllerTest extends AbstractTransformControllerTest
.param("resizePercentage", "false")
.param("allowEnlargement", "false")
.param("maintainAspectRatio", "true"))
.andExpect(status().is(OK.value()))
.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
@@ -338,10 +340,12 @@ public class ImageMagickControllerTest extends AbstractTransformControllerTest
.param("resizeWidth", "321")
.param("resizeHeight", "654")
.param("commandOptions", "( horrible command / );"))
.andExpect(status().is(OK.value()))
.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));
}
@Override

View File

@@ -140,7 +140,7 @@ public class LibreOfficeTransformer implements CustomTransformerFileAdaptor
}
catch (OfficeException e)
{
throw new TransformException(BAD_REQUEST.value(),
throw new TransformException(BAD_REQUEST,
"LibreOffice server conversion failed: \n" +
" from file: " + sourceFile + "\n" +
" to file: " + targetFile, e);
@@ -165,8 +165,7 @@ public class LibreOfficeTransformer implements CustomTransformerFileAdaptor
if (!targetFile.exists() || targetFile.length() == 0L)
{
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");
}
}
@@ -200,8 +199,7 @@ public class LibreOfficeTransformer implements CustomTransformerFileAdaptor
}
catch (IOException iox)
{
throw new TransformException(INTERNAL_SERVER_ERROR.value(),
"Error creating empty PDF file", iox);
throw new TransformException(INTERNAL_SERVER_ERROR, "Error creating empty PDF file", iox);
}
}
@@ -222,7 +220,7 @@ public class LibreOfficeTransformer implements CustomTransformerFileAdaptor
}
catch (OfficeException e)
{
throw new TransformException(BAD_REQUEST.value(),
throw new TransformException(BAD_REQUEST,
"LibreOffice metadata extract failed: \n" +
" from file: " + sourceFile, e);
}
@@ -244,7 +242,7 @@ public class LibreOfficeTransformer implements CustomTransformerFileAdaptor
}
catch (IOException e)
{
throw new TransformException(INTERNAL_SERVER_ERROR.value(), "Failed to write metadata to targetFile", e);
throw new TransformException(INTERNAL_SERVER_ERROR, "Failed to write metadata to targetFile", e);
}
}
}

View File

@@ -29,7 +29,7 @@ package org.alfresco.transform.libreoffice;
import org.alfresco.transform.base.AbstractHttpRequestTest;
/**
* Tests LibreOffice with a server test harness that talks to the TransformController using http.
* Tests LibreOffice using http and a server test harness.
*/
public class LibreOfficeHttpRequestTest extends AbstractHttpRequestTest
{

View File

@@ -59,7 +59,7 @@ import javax.annotation.PostConstruct;
import org.alfresco.transform.client.model.TransformReply;
import org.alfresco.transform.client.model.TransformRequest;
import org.alfresco.transform.libreoffice.transformers.LibreOfficeTransformer;
import org.alfresco.transform.base.AbstractTransformControllerTest;
import org.alfresco.transform.base.AbstractBaseTest;
import org.alfresco.transform.base.executors.RuntimeExec.ExecutionResult;
import org.alfresco.transform.base.model.FileRefEntity;
import org.alfresco.transform.base.model.FileRefResponse;
@@ -69,7 +69,6 @@ import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
@@ -79,11 +78,9 @@ import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
/**
* Test the LibreOfficeController without a server.
* Super class includes tests for the TransformController.
* Test LibreOffice.
*/
@WebMvcTest()
public class LibreOfficeControllerTest extends AbstractTransformControllerTest
public class LibreOfficeTest extends AbstractBaseTest
{
protected static final String ENGINE_CONFIG_NAME = "libreoffice_engine_config.json";
protected String targetMimetype = MIMETYPE_PDF;
@@ -132,12 +129,11 @@ public class LibreOfficeControllerTest extends AbstractTransformControllerTest
// The following is based on super.mockTransformCommand(...)
// This is because LibreOffice used JodConverter rather than a RuntimeExec
expectedSourceFileBytes = Files.readAllBytes(
sourceFileBytes = Files.readAllBytes(
getTestFile("quick." + sourceExtension, true).toPath());
expectedTargetFileBytes = Files.readAllBytes(
getTestFile("quick." + targetExtension, true).toPath());
sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype,
expectedSourceFileBytes);
sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype, sourceFileBytes);
doAnswer(invocation ->
{
@@ -160,7 +156,7 @@ public class LibreOfficeControllerTest extends AbstractTransformControllerTest
// Check the supplied source file has not been changed.
byte[] actualSourceFileBytes = Files.readAllBytes(sourceFile.toPath());
assertTrue(Arrays.equals(expectedSourceFileBytes, actualSourceFileBytes), "Source file is not the same");
assertTrue(Arrays.equals(sourceFileBytes, actualSourceFileBytes), "Source file is not the same");
return null;
}).when(javaExecutor).convert(any(), any());

View File

@@ -26,13 +26,12 @@
*/
package org.alfresco.transform.misc;
import org.alfresco.transform.base.AbstractTransformControllerTest;
import org.alfresco.transform.base.AbstractBaseTest;
import org.alfresco.transform.client.model.TransformRequest;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
@@ -56,10 +55,13 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.springframework.http.HttpStatus.OK;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest()
public class MiscControllerTest extends AbstractTransformControllerTest
/**
* Test Misc.
*/
public class MiscTest extends AbstractBaseTest
{
protected final String sourceEncoding = "UTF-8";
protected final String targetEncoding = "UTF-8";
@@ -75,11 +77,9 @@ public class MiscControllerTest extends AbstractTransformControllerTest
targetExtension = "txt";
expectedOptions = null;
expectedSourceSuffix = null;
expectedSourceFileBytes = readTestFile(sourceExtension);
sourceFileBytes = readTestFile(sourceExtension);
expectedTargetFileBytes = Files.readAllBytes(getTestFile("quick2." + targetExtension, true).toPath());
//expectedTargetFileBytes = null;
sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype,
expectedSourceFileBytes);
sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype, sourceFileBytes);
}
@Override
@@ -505,11 +505,13 @@ public class MiscControllerTest extends AbstractTransformControllerTest
}
return mockMvc.perform(requestBuilder)
.andExpect(status().is(OK.value()))
.andExpect(request().asyncStarted())
.andDo(MvcResult::getAsyncResult)
.andExpect(status().isOk())
.andExpect(header().string("Content-Disposition",
"attachment; filename*= " +
"attachment; filename*=" +
(targetEncoding == null ? "UTF-8" : targetEncoding) +
"''test_file." + targetExtension))
"''transform." + targetExtension))
.andReturn();
}

View File

@@ -29,7 +29,7 @@ package org.alfresco.transform.misc;
import org.alfresco.transform.base.AbstractHttpRequestTest;
/**
* Tests Misc with a server test harness that talks to the TransformController using http.
* Tests Misc using http and a server test harness.
*/
public class MiscTransformerHttpRequestTest extends AbstractHttpRequestTest
{

View File

@@ -31,7 +31,7 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
/**
* Tests PdfRenderer with a server test harness that talks to the TransformController using http.
* Tests PdfRenderer using http and a server test harness.
*/
public class AlfrescoPdfRendererHttpRequestTest extends AbstractHttpRequestTest
{

View File

@@ -45,6 +45,7 @@ import static org.springframework.http.MediaType.APPLICATION_PDF_VALUE;
import static org.springframework.http.MediaType.IMAGE_PNG_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 static org.springframework.util.StringUtils.getFilenameExtension;
@@ -59,8 +60,7 @@ import javax.annotation.PostConstruct;
import org.alfresco.transform.client.model.TransformReply;
import org.alfresco.transform.client.model.TransformRequest;
import org.alfresco.transform.base.TransformController;
import org.alfresco.transform.base.AbstractTransformControllerTest;
import org.alfresco.transform.base.AbstractBaseTest;
import org.alfresco.transform.pdfrenderer.transformers.PdfRendererTransformer;
import org.alfresco.transform.base.executors.RuntimeExec;
import org.alfresco.transform.base.executors.RuntimeExec.ExecutionResult;
@@ -70,23 +70,20 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.stubbing.Answer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
/**
* Test the AlfrescoPdfRendererController without a server.
* Super class includes tests for the TransformController.
* Test PdfRenderer.
*/
@WebMvcTest()
public class AlfrescoPdfRendererControllerTest extends AbstractTransformControllerTest
public class PdfRendererTest extends AbstractBaseTest
{
private static final String ENGINE_CONFIG_NAME = "pdfrenderer_engine_config.json";
@@ -143,10 +140,9 @@ public class AlfrescoPdfRendererControllerTest extends AbstractTransformControll
expectedOptions = null;
expectedSourceSuffix = null;
expectedSourceFileBytes = readTestFile(sourceExtension);
sourceFileBytes = readTestFile(sourceExtension);
expectedTargetFileBytes = readTargetFileBytes ? readTestFile(targetExtension) : null;
sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype,
expectedSourceFileBytes);
sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype, sourceFileBytes);
when(mockTransformCommand.execute(any(), anyLong())).thenAnswer(
(Answer<RuntimeExec.ExecutionResult>) invocation -> {
@@ -195,7 +191,7 @@ public class AlfrescoPdfRendererControllerTest extends AbstractTransformControll
// Check the supplied source file has not been changed.
byte[] actualSourceFileBytes = Files.readAllBytes(new File(actualSource).toPath());
assertTrue(Arrays.equals(expectedSourceFileBytes, actualSourceFileBytes),
assertTrue(Arrays.equals(sourceFileBytes, actualSourceFileBytes),
"Source file is not the same");
return mockExecutionResult;
@@ -224,10 +220,12 @@ public class AlfrescoPdfRendererControllerTest extends AbstractTransformControll
.param("height", "654")
.param("allowPdfEnlargement", "true")
.param("maintainPdfAspectRatio", "true"))
.andExpect(status().is(OK.value()))
.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
@@ -248,10 +246,12 @@ public class AlfrescoPdfRendererControllerTest extends AbstractTransformControll
.param("height", "654")
.param("allowPdfEnlargement", "false")
.param("maintainPdfAspectRatio", "false"))
.andExpect(status().is(OK.value()))
.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));
}
@Override

View File

@@ -30,7 +30,7 @@ import org.alfresco.transform.base.AbstractHttpRequestTest;
import org.springframework.util.LinkedMultiValueMap;
/**
* Tests Tika with a server test harness that talks to the TransformController using http.
* Tests Tika using http and a server test harness.
*/
public class TikaHttpRequestTest extends AbstractHttpRequestTest
{

View File

@@ -26,8 +26,7 @@
*/
package org.alfresco.transform.tika;
import org.alfresco.transform.base.AbstractTransformControllerTest;
import org.alfresco.transform.base.TransformController;
import org.alfresco.transform.base.AbstractBaseTest;
import org.alfresco.transform.base.executors.RuntimeExec;
import org.alfresco.transform.base.model.FileRefEntity;
import org.alfresco.transform.base.model.FileRefResponse;
@@ -41,7 +40,6 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.stubbing.Answer;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
@@ -116,11 +114,9 @@ import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE;
import static org.springframework.util.StringUtils.getFilenameExtension;
/**
* Test the TikaController without a server.
* Super class includes tests for the TransformController.
* Test Tika.
*/
@WebMvcTest()
public class TikaControllerTest extends AbstractTransformControllerTest
public class TikaTest extends AbstractBaseTest
{
private static final String ENGINE_CONFIG_NAME = "tika_engine_config.json";
private static final String EXPECTED_XHTML_CONTENT_CONTAINS = "<p>The quick brown fox jumps over the lazy dog</p>";
@@ -166,10 +162,9 @@ public class TikaControllerTest extends AbstractTransformControllerTest
expectedOptions = null;
expectedSourceSuffix = null;
expectedSourceFileBytes = readTestFile(sourceExtension);
sourceFileBytes = readTestFile(sourceExtension);
expectedTargetFileBytes = readTargetFileBytes ? readTestFile(targetExtension) : null;
sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype,
expectedSourceFileBytes);
sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype, sourceFileBytes);
when(mockTransformCommand.execute(any(), anyLong())).thenAnswer(
(Answer<RuntimeExec.ExecutionResult>) invocation -> {
@@ -217,7 +212,7 @@ public class TikaControllerTest extends AbstractTransformControllerTest
// Check the supplied source file has not been changed.
byte[] actualSourceFileBytes = readAllBytes(new File(actualSource).toPath());
Assertions.assertArrayEquals(expectedSourceFileBytes, actualSourceFileBytes,
Assertions.assertArrayEquals(sourceFileBytes, actualSourceFileBytes,
"Source file is not the same");
return mockExecutionResult;
@@ -245,7 +240,7 @@ public class TikaControllerTest extends AbstractTransformControllerTest
MvcResult result = mockMvc.perform(requestBuilder)
.andExpect(MockMvcResultMatchers.status().is(OK.value()))
.andExpect(MockMvcResultMatchers.header().string("Content-Disposition",
"attachment; filename*= UTF-8''quick." + this.targetExtension)).
"attachment; filename*=UTF-8''transform." + this.targetExtension)).
andReturn();
String content = result.getResponse().getContentAsString();
assertTrue(content.contains(expectedContentContains),
@@ -270,7 +265,6 @@ public class TikaControllerTest extends AbstractTransformControllerTest
public void testImmutableEmptyMap()
{
// See ACS-373
TransformController controller = getController();
ProbeTestTransform probeTestTransform = getProbeTestTransform();
ReflectionTestUtils.setField(probeTestTransform, "livenessTransformEnabled", true);
probeTestTransform.doTransformOrNothing(httpServletRequest, true, controller);
@@ -284,14 +278,6 @@ public class TikaControllerTest extends AbstractTransformControllerTest
super.simpleTransformTest();
}
@Test
@Override
public void testDelayTest() throws Exception
{
mockTransformCommand(PDF, TXT, MIMETYPE_PDF, true);
super.testDelayTest();
}
@Test
@Override
public void noTargetFileTest()
@@ -552,7 +538,7 @@ public class TikaControllerTest extends AbstractTransformControllerTest
MvcResult result = mockMvc.perform(requestBuilder)
.andExpect(MockMvcResultMatchers.status().is(OK.value()))
.andExpect(MockMvcResultMatchers.header().string("Content-Disposition",
"attachment; filename*= UTF-8''quick." + targetExtension)).
"attachment; filename*=UTF-8''transform." + targetExtension)).
andReturn();
byte[] bytes = result.getResponse().getContentAsByteArray();
@@ -577,7 +563,7 @@ public class TikaControllerTest extends AbstractTransformControllerTest
NOT_EXTRACT_BOOKMARKS_TEXT, "true"))
.andExpect(MockMvcResultMatchers.status().is(OK.value()))
.andExpect(MockMvcResultMatchers.header().string("Content-Disposition",
"attachment; filename*= UTF-8''quick." + targetExtension));
"attachment; filename*=UTF-8''transform." + targetExtension));
}
@Override

View File

@@ -63,7 +63,7 @@ public class TransformConfigResourceReader
}
catch (IOException e)
{
throw new TransformException(INTERNAL_SERVER_ERROR.value(), "Could not read " + engineConfigLocation, e);
throw new TransformException(INTERNAL_SERVER_ERROR, "Could not read " + engineConfigLocation, e);
}
}
}

View File

@@ -21,23 +21,25 @@
*/
package org.alfresco.transform.common;
import org.springframework.http.HttpStatus;
public class TransformException extends RuntimeException
{
private final int statusCode;
private final HttpStatus statusCode;
public TransformException(int statusCode, String message)
public TransformException(HttpStatus statusCode, String message)
{
super(message);
this.statusCode = statusCode;
}
public TransformException(int statusCode, String message, Throwable cause)
public TransformException(HttpStatus statusCode, String message, Throwable cause)
{
super(message, cause);
this.statusCode = statusCode;
}
public int getStatusCode()
public HttpStatus getStatusCode()
{
return statusCode;
}

View File

@@ -21,11 +21,10 @@
*/
package org.alfresco.transform.registry;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static java.util.Collections.emptySet;
import static java.util.Map.Entry;
import static java.util.stream.Collectors.toMap;
import org.alfresco.transform.common.TransformException;
import org.alfresco.transform.config.TransformOption;
import org.alfresco.transform.config.TransformOptionGroup;
import org.alfresco.transform.config.TransformOptionValue;
import java.util.ArrayList;
import java.util.HashMap;
@@ -35,10 +34,12 @@ import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import org.alfresco.transform.config.TransformOption;
import org.alfresco.transform.config.TransformOptionGroup;
import org.alfresco.transform.config.TransformOptionValue;
import org.alfresco.transform.common.TransformException;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static java.util.Collections.emptySet;
import static java.util.Map.Entry;
import static java.util.stream.Collectors.toMap;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
class TransformRegistryHelper
{
@@ -113,12 +114,12 @@ class TransformRegistryHelper
{
if (sourceMimetype == null)
{
throw new TransformException(400, "Null value provided for sourceMimetype, please provide a value");
throw new TransformException(BAD_REQUEST, "Null value provided for sourceMimetype, please provide a value");
}
if (targetMimetype == null)
{
throw new TransformException(400, "Null value provided for tragetMimetype, please provide a value");
throw new TransformException(BAD_REQUEST, "Null value provided for targetMimetype, please provide a value");
}
final Map<String, List<SupportedTransform>> targetMap = data.retrieveTransforms(