ATS-175 : T-Engine code cleanup

This commit is contained in:
Cezar.Leahu
2018-10-25 18:21:50 +03:00
parent ba8707c762
commit d85c03d362
42 changed files with 2042 additions and 1475 deletions

View File

@@ -11,14 +11,23 @@
*/
package org.alfresco.transformer;
import static org.alfresco.transformer.fs.FileManager.createAttachment;
import static org.alfresco.transformer.fs.FileManager.createSourceFile;
import static org.alfresco.transformer.fs.FileManager.createTargetFile;
import static org.alfresco.transformer.fs.FileManager.createTargetFileName;
import static org.alfresco.transformer.logging.StandardMessages.ENTERPRISE_LICENCE;
import java.io.File;
import java.util.HashMap;
import java.util.Arrays;
import java.util.Map;
import java.util.StringJoiner;
import javax.servlet.http.HttpServletRequest;
import org.alfresco.util.exec.RuntimeExec;
import org.alfresco.transformer.executors.PdfRendererCommandExecutor;
import org.alfresco.transformer.logging.LogEntry;
import org.alfresco.transformer.probes.ProbeTestTransform;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
@@ -52,69 +61,49 @@ import org.springframework.web.multipart.MultipartFile;
@Controller
public class AlfrescoPdfRendererController extends AbstractTransformerController
{
private static final String EXE = "/usr/bin/alfresco-pdf-renderer";
private static final Log logger = LogFactory.getLog(AlfrescoPdfRendererController.class);
@Autowired
private PdfRendererCommandExecutor commandExecutor;
@Autowired
public AlfrescoPdfRendererController()
{
logger = LogFactory.getLog(AlfrescoPdfRendererController.class);
logger.info("-----------------------------------------------------------------------------------------------------------------------------------------------------------");
logEnterpriseLicenseMessage();
Arrays.stream(ENTERPRISE_LICENCE.split("\\n")).forEach(logger::info);
logger.info("alfresco-pdf-renderer uses the PDFium library from Google Inc. See the license at https://pdfium.googlesource.com/pdfium/+/master/LICENSE or in /pdfium.txt");
logger.info("-----------------------------------------------------------------------------------------------------------------------------------------------------------");
setTransformCommand(createTransformCommand());
setCheckCommand(createCheckCommand());
}
@Override
protected String getTransformerName()
public String getTransformerName()
{
return "Alfresco PDF Renderer";
}
private static RuntimeExec createTransformCommand()
@Override
public String version()
{
RuntimeExec runtimeExec = new RuntimeExec();
Map<String, String[]> commandsAndArguments = new HashMap<>();
commandsAndArguments.put(".*", new String[]{EXE, "SPLIT:${options}", "${source}", "${target}"});
runtimeExec.setCommandsAndArguments(commandsAndArguments);
Map<String, String> defaultProperties = new HashMap<>();
defaultProperties.put("key", null);
runtimeExec.setDefaultProperties(defaultProperties);
runtimeExec.setErrorCodes("1");
return runtimeExec;
}
private static RuntimeExec createCheckCommand()
{
RuntimeExec runtimeExec = new RuntimeExec();
Map<String, String[]> commandsAndArguments = new HashMap<>();
commandsAndArguments.put(".*", new String[]{EXE, "--version"});
runtimeExec.setCommandsAndArguments(commandsAndArguments);
return runtimeExec;
return commandExecutor.version();
}
@Override
protected ProbeTestTransform getProbeTestTransform()
public ProbeTestTransform getProbeTestTransform()
{
// See the Javadoc on this method and Probes.md for the choice of these values.
return new ProbeTestTransform(this,"quick.pdf", "quick.png",
return new ProbeTestTransform(this, logger, "quick.pdf", "quick.png",
7455, 1024, 150, 10240, 60*20+1, 60*15-15)
{
@Override
protected void executeTransformCommand(File sourceFile, File targetFile)
{
AlfrescoPdfRendererController.this.executeTransformCommand("", sourceFile, targetFile, null);
commandExecutor.run("", sourceFile, targetFile, null);
}
};
}
@Override
protected void processTransform(File sourceFile, File targetFile,
public void processTransform(File sourceFile, File targetFile,
Map<String, String> transformOptions, Long timeout)
{
String page = transformOptions.get("page");
@@ -137,7 +126,7 @@ public class AlfrescoPdfRendererController extends AbstractTransformerController
String options = buildTransformOptions(pageOption, widthOption, heightOption,
allowEnlargementOption, maintainAspectRatioOption);
executeTransformCommand(options, sourceFile, targetFile, timeout);
commandExecutor.run(options, sourceFile, targetFile, timeout);
}
@Deprecated
@@ -155,19 +144,26 @@ public class AlfrescoPdfRendererController extends AbstractTransformerController
@RequestParam(value = "maintainAspectRatio", required = false) Boolean maintainAspectRatio)
{
String targetFilename = createTargetFileName(sourceMultipartFile.getOriginalFilename(), targetExtension);
getProbeTestTransform().incrementTransformerCount();
File sourceFile = createSourceFile(request, sourceMultipartFile);
File targetFile = createTargetFile(request, targetFilename);
// Both files are deleted by TransformInterceptor.afterCompletion
String options = buildTransformOptions(page, width, height, allowEnlargement,
maintainAspectRatio);
executeTransformCommand(options, sourceFile, targetFile, timeout);
return createAttachment(targetFilename, targetFile, testDelay);
commandExecutor.run(options, sourceFile, targetFile, timeout);
final ResponseEntity<Resource> body = createAttachment(targetFilename, targetFile);
LogEntry.setTargetSize(targetFile.length());
long time = LogEntry.setStatusCodeAndMessage(200, "Success");
time += LogEntry.addDelay(testDelay);
getProbeTestTransform().recordTransformTime(time);
return body;
}
public String buildTransformOptions(Integer page,Integer width,Integer height,Boolean allowEnlargement,Boolean maintainAspectRatio)
private static String buildTransformOptions(Integer page,Integer width,Integer height,Boolean
allowEnlargement,Boolean maintainAspectRatio)
{
StringJoiner args = new StringJoiner(" ");
if (width != null && width >= 0)

View File

@@ -12,6 +12,8 @@
package org.alfresco.transformer;
import io.micrometer.core.instrument.MeterRegistry;
import org.alfresco.transformer.executors.PdfRendererCommandExecutor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
@@ -27,9 +29,15 @@ public class Application
@Value("${container.name}")
private String containerName;
@Bean MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
@Bean
public MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
return registry -> registry.config().commonTags("containerName", containerName);
}
@Bean
public PdfRendererCommandExecutor commandExecutor() {
return new PdfRendererCommandExecutor();
}
public static void main(String[] args)
{

View File

@@ -0,0 +1,43 @@
package org.alfresco.transformer.executors;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.util.exec.RuntimeExec;
import org.springframework.stereotype.Component;
/**
*/
@Component
public class PdfRendererCommandExecutor extends AbstractCommandExecutor
{
private static final String EXE = "/usr/bin/alfresco-pdf-renderer";
@Override
protected RuntimeExec createTransformCommand()
{
RuntimeExec runtimeExec = new RuntimeExec();
Map<String, String[]> commandsAndArguments = new HashMap<>();
commandsAndArguments.put(".*",
new String[]{EXE, "SPLIT:${options}", "${source}", "${target}"});
runtimeExec.setCommandsAndArguments(commandsAndArguments);
Map<String, String> defaultProperties = new HashMap<>();
defaultProperties.put("key", null);
runtimeExec.setDefaultProperties(defaultProperties);
runtimeExec.setErrorCodes("1");
return runtimeExec;
}
@Override
protected RuntimeExec createCheckCommand()
{
RuntimeExec runtimeExec = new RuntimeExec();
Map<String, String[]> commandsAndArguments = new HashMap<>();
commandsAndArguments.put(".*", new String[]{EXE, "--version"});
runtimeExec.setCommandsAndArguments(commandsAndArguments);
return runtimeExec;
}
}

View File

@@ -25,19 +25,48 @@
*/
package org.alfresco.transformer;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.when;
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.IOException;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.alfresco.transform.client.model.TransformReply;
import org.alfresco.transform.client.model.TransformRequest;
import org.alfresco.transformer.executors.PdfRendererCommandExecutor;
import org.alfresco.transformer.model.FileRefEntity;
import org.alfresco.transformer.model.FileRefResponse;
import org.alfresco.util.exec.RuntimeExec;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.stubbing.Answer;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.util.StringUtils;
/**
* Test the AlfrescoPdfRendererController without a server.
@@ -47,22 +76,111 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
@WebMvcTest(AlfrescoPdfRendererController.class)
public class AlfrescoPdfRendererControllerTest extends AbstractTransformerControllerTest
{
@Mock
private RuntimeExec.ExecutionResult mockExecutionResult;
@Mock
private RuntimeExec mockTransformCommand;
@Mock
private RuntimeExec mockCheckCommand;
@SpyBean
private PdfRendererCommandExecutor commandExecutor;
@SpyBean
private AlfrescoPdfRendererController controller;
@Before
public void before() throws Exception
public void before() throws IOException
{
controller.setAlfrescoSharedFileStoreClient(alfrescoSharedFileStoreClient);
super.controller = controller;
super.mockTransformCommand(controller, "pdf", "png", "application/pdf", true);
commandExecutor.setTransformCommand(mockTransformCommand);
commandExecutor.setCheckCommand(mockCheckCommand);
mockTransformCommand("pdf", "png", "application/pdf", true);
}
@Override
public void mockTransformCommand(String sourceExtension,
String targetExtension, String sourceMimetype,
boolean readTargetFileBytes) throws IOException
{
this.sourceExtension = sourceExtension;
this.targetExtension = targetExtension;
this.sourceMimetype = sourceMimetype;
expectedOptions = null;
expectedSourceSuffix = null;
expectedSourceFileBytes = readTestFile(sourceExtension);
expectedTargetFileBytes = readTargetFileBytes ? readTestFile(targetExtension) : null;
sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype, expectedSourceFileBytes);
when(mockTransformCommand.execute(any(), anyLong())).thenAnswer(
(Answer<RuntimeExec.ExecutionResult>) invocation -> {
Map<String, String> actualProperties = invocation.getArgument(0);
assertEquals("There should be 3 properties", 3, actualProperties.size());
String actualOptions = actualProperties.get("options");
String actualSource = actualProperties.get("source");
String actualTarget = actualProperties.get("target");
String actualTargetExtension = StringUtils.getFilenameExtension(actualTarget);
assertNotNull(actualSource);
assertNotNull(actualTarget);
if (expectedSourceSuffix != null)
{
assertTrue("The source file \""+actualSource+"\" should have ended in \""+expectedSourceSuffix+"\"", actualSource.endsWith(expectedSourceSuffix));
actualSource = actualSource.substring(0, actualSource.length()-expectedSourceSuffix.length());
}
assertNotNull(actualOptions);
if (expectedOptions != null)
{
assertEquals("expectedOptions", expectedOptions, actualOptions);
}
Long actualTimeout = invocation.getArgument(1);
assertNotNull(actualTimeout);
if (expectedTimeout != null)
{
assertEquals("expectedTimeout", expectedTimeout, actualTimeout);
}
// Copy a test file into the target file location if it exists
int i = actualTarget.lastIndexOf('_');
if (i >= 0)
{
String testFilename = actualTarget.substring(i+1);
File testFile = getTestFile(testFilename, false);
File targetFile = new File(actualTarget);
generateTargetFileFromResourceFile(actualTargetExtension, testFile,
targetFile);
}
// Check the supplied source file has not been changed.
byte[] actualSourceFileBytes = Files.readAllBytes(new File(actualSource).toPath());
assertTrue("Source file is not the same", Arrays.equals(expectedSourceFileBytes, actualSourceFileBytes));
return mockExecutionResult;
});
when(mockExecutionResult.getExitValue()).thenReturn(0);
when(mockExecutionResult.getStdErr()).thenReturn("STDERROR");
when(mockExecutionResult.getStdOut()).thenReturn("STDOUT");
}
@Override
protected AbstractTransformerController getController()
{
return controller;
}
@Test
public void optionsTest() throws Exception
{
expectedOptions = "--width=321 --height=654 --allow-enlargement --maintain-aspect-ratio --page=2";
mockMvc.perform(MockMvcRequestBuilders.fileUpload("/transform")
mockMvc.perform(MockMvcRequestBuilders.multipart("/transform")
.file(sourceFile)
.param("targetExtension", targetExtension)
@@ -82,7 +200,7 @@ public class AlfrescoPdfRendererControllerTest extends AbstractTransformerContro
public void optionsNegateBooleansTest() throws Exception
{
expectedOptions = "--width=321 --height=654 --page=2";
mockMvc.perform(MockMvcRequestBuilders.fileUpload("/transform")
mockMvc.perform(MockMvcRequestBuilders.multipart("/transform")
.file(sourceFile)
.param("targetExtension", targetExtension)
@@ -106,4 +224,64 @@ public class AlfrescoPdfRendererControllerTest extends AbstractTransformerContro
transformRequest.setSourceMediaType(MediaType.APPLICATION_PDF_VALUE);
transformRequest.setTargetMediaType(MediaType.IMAGE_PNG_VALUE);
}
@Test
public void badExitCodeTest() throws Exception
{
when(mockExecutionResult.getExitValue()).thenReturn(1);
mockMvc.perform(mockMvcRequest("/transform", sourceFile, "targetExtension", "xxx"))
.andExpect(status().is(400))
.andExpect(status().reason(containsString("Transformer exit code was not 0: \nSTDERR")));
}
@Test
public void testPojoTransform() throws Exception
{
// Files
String sourceFileRef = UUID.randomUUID().toString();
File sourceFile = getTestFile("quick." + sourceExtension, true);
String targetFileRef = UUID.randomUUID().toString();
// Transformation Request POJO
TransformRequest transformRequest = new TransformRequest();
transformRequest.setRequestId("1");
transformRequest.setSchema(1);
transformRequest.setClientData("Alfresco Digital Business Platform");
transformRequest.setTransformRequestOptions(new HashMap<>());
transformRequest.setSourceReference(sourceFileRef);
transformRequest.setSourceExtension(sourceExtension);
transformRequest.setSourceSize(sourceFile.length());
transformRequest.setTargetExtension(targetExtension);
// HTTP Request
HttpHeaders headers = new HttpHeaders();
headers.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=quick." + sourceExtension);
ResponseEntity<Resource> response = new ResponseEntity<>(new FileSystemResource(
sourceFile), headers, HttpStatus.OK);
when(alfrescoSharedFileStoreClient.retrieveFile(sourceFileRef)).thenReturn(response);
when(alfrescoSharedFileStoreClient.saveFile(any())).thenReturn(new FileRefResponse(new FileRefEntity(targetFileRef)));
when(mockExecutionResult.getExitValue()).thenReturn(0);
// Update the Transformation Request with any specific params before sending it
updateTransformRequestWithSpecificOptions(transformRequest);
// Serialize and call the transformer
String tr = objectMapper.writeValueAsString(transformRequest);
String transformationReplyAsString = mockMvc.perform(MockMvcRequestBuilders.post("/transform")
.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).content(tr))
.andExpect(status().is(HttpStatus.CREATED.value()))
.andReturn().getResponse().getContentAsString();
TransformReply transformReply = objectMapper.readValue(transformationReplyAsString, TransformReply.class);
// Assert the reply
assertEquals(transformRequest.getRequestId(), transformReply.getRequestId());
assertEquals(transformRequest.getClientData(), transformReply.getClientData());
assertEquals(transformRequest.getSchema(), transformReply.getSchema());
}
}

View File

@@ -25,7 +25,6 @@
*/
package org.alfresco.transformer;
import org.alfresco.transformer.AbstractHttpRequestTest;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
@@ -48,5 +47,5 @@ public class AlfrescoPdfRendererHttpRequestTest extends AbstractHttpRequestTest
protected String getSourceExtension()
{
return "pdf";
};
}
}